配信編
前回の実装編では、iOS/AndroidのTokenをAzure Notification Hubsに登録し、コンソールからPush通知を送信/受信できることを確認しました。
今回は、プログラムでAzure Notification HubsnのPush通知の送信や登録の管理等を行って行きます。
Azure Notification Hubsには、Notification Hubs REST APIsが提供されていおり、JavaとNode.jsのSDKも提供されています。
REST APIを直接使用するには、認証,アクセストークンなどの仕組みを理解しなければならないため、それらをラップしたSDKを使用することで効率的に開発することが出来ます。
- Java ... Azure/azure-notificationhubs-java-backend
- Node.js ... Notification Hubs
※ PHPとPythonはラッパーサンプルが提供されています。
- PHP ... azure-notificationhubs-samples/notificationhubs-rest-php at master · Azure/azure-notificationhubs-samples
- Python ...azure-notificationhubs-samples/notificationhubs-rest-python at master · Azure/azure-notificationhubs-samples
JavaからPush通知
SDKのビルド
-
GitHubからAzure/azure-notificationhubs-java-backend をPCローカルにcloneする。
$ git clone https://github.com/Azure/azure-notificationhubs-java-backend.git
-
Maven構成のプロジェクトとなっているので、以下のコードでビルド。
$ mvn clean package
-
TESTが失敗し、"BUILD FAILURE"となる場合は、暫定的に以下の行をコメントアウトして、再ビルド。
<!-- <testSourceDirectory>test</testSourceDirectory> <testResources> <testResource> <directory>test</directory> <excludes> <exclude>**/*.java</exclude> </excludes> </testResource> </testResources> -->
-
ビルドに成功すると、target ディレクトリにjarファイルが作成される。
NotificationHubs-0.0.3.jar
アプリの実装
-
Notification Hubのクライアントのインスタンスを作成
String connectionString = "Endpoint=sb://x.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=..."; String hubPath = "AzureNotificationHubsExample"; NotificationHub hub = new NotificationHub(connectionString, hubPath);
- connectionString に、Notification Hubの[DefaultFullSharedAccessSignature]の文字列を指定
- hubPath に、Notification Hubの名前を指定
-
Push通知の送信
-
iOSへ送信する
String message = "Hello Azure World!"; String body = String.format("{\"aps\":{\"alert\":\"%s\"}}", message); Notification notifiation = Notification.createAppleNotifiation(body); hub.sendNotification(notifiation);
-
Androidへ送信する
String message = "Hello Azure World!"; String body = String.format("{\"data\":{\"message\":\"%s\"}}", message); Notification notifiation = Notification.createGcmNotifiation(body); hub.sendNotification(notifiation);
-
タグを使って指定した範囲にPush通知を送信
iOS/Android アプリからAzure Notification HubsへのPush通知のトークンの登録時にタグを指定することが出来ます。
タグに、カテゴリーやグループの識別子や、ユーザー、デバイス識別子(UUID等)を設定しておくことで、送信先の範囲を絞り込むことに使用すること出来ます。-
iOS/Android アプリからタグを指定してPush通知のトークンを登録
Azure Notification Hubsを使用してiOSとAndroidにPush通知を行う (2) ~実装編~で、実装したコードの登録のロジックに、UUIDのタグを追加します。-
iOS
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { // NotificationHubへ登録 let hub = SBNotificationHub( connectionString: "Endpoint=sb://x.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=...", notificationHubPath: "AzureNotificationHubsExample") // タグにUUIDを追加 let uuid = NSUUID().UUIDString; let tags: Set<String> = ["UUID:\(uuid)"] hub.registerNativeWithDeviceToken(deviceToken, tags: tags) { (error) in if (error != nil) { print("Error registering for notifications.", error) } else { print("Success registering for notifications.", deviceToken) } } }
-
-
Android
private void sendRegistrationToServer(String refreshedToken) { NotificationHub hub = new NotificationHub( "AzureNotificationHubsExample", "Endpoint=sb://x.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=...", this); try { // タグにUUIDを追加 String uuid = UUID.randomUUID().toString(); String[] tags = {"UUID:" + uuid}; Registration registration = hub.register(refreshedToken, tags); String registrationId = registration.getRegistrationId(); Log.d(TAG, "Registration ID: " + registrationId); } catch (Exception e) { e.printStackTrace(); } }
-
タグを指定してPush通知を送信
タグにUUIDを指定Set<String> tags = new HashSet<String>(); tags.add("UUID:4151CA6C-FE7B-48C4-83AC-F1FEDD8C37AA"); hub.sendNotification(notifiation, tags);
UUIDのデバイスにのみPush通知が送信されます。
-
-
登録の編集
タグに設定したカテゴリーやグループの識別子を編集することが可能です。- 登録を取得
RegistrationIdで取得Registration registration = hub.getRegistration(registrationId);
Tagで検索CollectionResult collectionResult = hub.getRegistrationsByTag("SINGLE"); for (Registration registration:collectionResult.getRegistrations()) { // do logic }
- 登録を更新
// タグを編集 Set<String> tags = new HashSet<String>(); tags.add("AGE_GROUP:F2"); tags.add("FEMALE"); tags.add("SINGLE"); registration.setTags(tags); hub.updateRegistration(registration);
- 登録を削除
hub.deleteRegistration(registrationId);
-
デバイスの登録
SDKからもPush通知のトークンの登録が出来ます。Registration reg = null; switch (platform) { case IOS: reg = new AppleRegistration(token); break; case ANDROID: reg = new GcmRegistration(token); break; default: } reg.getTags().add("UUID:" + uuid); reg.getTags().add("PLATFORM:" + platform); Registration registration = hub.createRegistration(reg); String registrationId = registration.getRegistrationId();
-
補足とまとめ
- Azure Notification Hubsは、同時に複数デバイスにPush通知の送信が出来る。
- 送信対象のデバイスはタグで絞り込むことが出来る。
- プラットフォーム毎にPush通知を送信しなければならない。
- プラットフォームを意識しないで送信することも出来れば良かったのだが...
- APNS/FCMのPushのトークンを使用して、Push通知の送信は出来ない。
- 登録時に発行されるRegistrationIdを指定して、Push通知の送信は出来ない。
- デバイス個々にPush通知を送信をしたい場合は、タグにデバイス識別子を設定する工夫が必要。
- 登録の更新でトークンを更新することは出来ない。Pushのトークンのリフレッシュが発生した場合、登録は削除と作成しなければならない。
- 登録時に発行されるRegistrationIdが、iOSのSDKでは取得できない...
- アプリのサービスを想定すると、個人情報やデバイス情報などとPush通知をまとめて管理する必要があると思うので、各プラットフォームが直接Azure Notification Hubsに登録するのではなく、Web App サーバでAPIで登録を管理した方がよいと考える。
Push通知は、バックエンドのAnalyticsの情報を元にターゲットの絞込やメッセージの作成をすることが想定されるので、mBaaSとしてそのあたりの強化を期待したい