NotificationHub#startを呼んだ際、何が起きているのか

概要

先日、Notification HubsのAndroid用の現行SDKを調べる機会があったのですが、 NotificationHub#startを呼んだだけで基本的な処理が完了するようになっており、とても驚きました。

この記事では、そのstartを呼んだ際に何が起きているのか*1を備忘録としてまとめておきます。 ※Firebase関連の説明は省きます

対象

Androidアプリ開発者でNotification Hubsの現行SDKを使う方

Notification Hubsとは

Notification Hubsとは、AndroidiOS等のプラットフォームへの通知を管理するAzureのサービスです。
詳細はこちら

登場する単語

  • NotificationHub ...Notification Hubs関連の処理をまとめるクラス
  • Installation ...デバイスへの通知処理を管理するためのデータのまとまり
  • InstallationAdapter ...Installationを送信することで、デバイスの登録処理を行うクラス
  • 〇〇Visitor ...Installationで使用するデータを保存するクラス
  • バイストーク ...FCM等から払い出される各デバイスに一意な文字列
    NotificationHub内では、PushChannelVisitorが管理する

Installationに関してはAzure docsの説明が参考になります。

従来のRegistrationと比較すると、プッシュ通知に必要なプロパティをひとまとめにした強化版とのことです。

大まかな処理の流れ

startを呼んだ際の流れは、

  1. NotificationHub#startを呼ぶことで、Applicationの登録やInstallationAdapterクラスの生成、NotificationHubクラスの生成等が行われる
  2. NotificationHubExtension#fetchPushChannelが呼ばれる
  3. (fetchPushChannel内で)FirebaseMessagingService#getTokenが呼ばれ、受け取ったデバイストークンをPushChannelVisitorに保存する
  4. (fetchPushChannel内で)NotificationHub#beginInstanceInstallationUpdateが呼ばれ、Installationの登録処理が始まる
  5. (beginInstanceInstallationUpdate内で)〇〇Visitorから各パラメータ(デバイストークンやタグ等)を取得し、新しいInstallationを作成する
  6. (beginInstanceInstallationUpdate内で)InstallationAdapter#saveInstallationが呼ばれる
  7. (saveInstallation内で)Notification Hubリソースに対して同Installationを登録するリクエストを送信する

となっています。

また、二回目以降(デバイストークンが更新された場合)の登録処理だと、 FirebaseMessagingServiceを継承したFirebaseReceiver#onNewTokenが呼ばれたタイミングで、受け取ったデバイストークンをPushChannelVisitorに保存します。
その後はstartが呼ばれた際の登録処理と同じ流れのようです。

シーケンス

NotificationHub#startのシーケンス図
NotificationHub#startのシーケンス図
※省略した部分

  • InstallationAdapterの区別(DebounceInstallationAdapter, NotificationHubInstallationAdapter, PushChannelValidationAdapter)
  • NotificationHubとNotificationHubExtensionの区別
  • 登録リクエストを送信する部分の詳細
  • 保持しているデバイストークンと同じデバイストークンを受け取ったケース

その他のメモ

  • アプリ側にconnectionStringを保持する必要があるので、要注意
  • DebounceInstallationAdapterは(同じ内容の)登録処理が何度も走るのを防ぐもの
  • Installation登録処理のインターバルは2000ミリ秒
  • 同じ内容のInstallation処理を送るための待ち時間のデフォルトは一日
  • この現行SDKを使用してInstallationを登録した場合、Installationの有効期限は90日になっている
  • Notification Hubsのテスト送信において、特定のinstallationIdを持つデバイスに通知を送信したい場合は "$installationId:{<対象のinstallationId>}" をタグに設定する
  • Notification Hubsのテスト送信において、特定のuserIdを持つデバイスに通知を送信したい場合は "$userId:{<対象のinstallationId>}" をタグに設定する
  • ドキュメントの設定手順を見る限り、Firebase MessagingのレガシーAPIを使用しているようなので、notification messageのkeyにバッジカウントが存在しない
  • 初期化を遅延させたい場合は、firebase_messaging_auto_init_enabledをfalseにしても意味はなく、NotificationHub#setIsEnabledを呼ぶ必要がある(そうしないと、NotificationHub初期化時にgetTokenが呼ばれてしまう)

参考

*1:decompileしたコードを読んだだけのため、間違い等あると思います