プッシュ通知方式の方針
Status: Accepted
要約
- このアプリでは以下のユースケースでプッシュ通知を送信します
- 時間割の開始通知
- 時間割の開始通知の通知方式として、リモート通知を採用します
- リモート通知の送信は、Android、iOS、iPadOSのいずれに対してもFirebase Cloud Messaging (FCM)を介して行います
- 時間割の開始通知のリモート通知の宛先指定種別としては、デバイス宛を採用します
- マルチキャスト送信を用いて、複数のデバイスへ同一のメッセージを一括送信します
コンテキスト
モバイルアプリでは、ユーザがモバイル端末を携帯しており通知の確認率が高いという特性から、 様々なシーンでプッシュ通知が活用されています。 このアプリでも、時間割の開始をチームメンバーへ通知するためにプッシュ通知を利用します。
モバイルアプリにおけるプッシュ通知の通知方式としては、大別すると以下の方式があります。
- リモート通知
- ローカル通知
- アプリへの通知機能の組み込み(例:WebSocketを用いた通知)
- その他の既存サービスを用いた通知(例:SMS、Email)
ここでは上記の通知方式を比較し、このアプリで利用するプッシュ通知の通知方式について検討します。
議論
このアプリにおけるプッシュ通知のユースケース
このアプリでは、以下の場面でプッシュ通知を利用します。
ユースケース | 通知の目的 | 送信条件(トリガー) | 送信先 | 送信先ごとの通知内容カスタマイズ | 送信頻度 | アプリ非利用時の通知 |
---|---|---|---|---|---|---|
時間割の開始通知 | チームの当日の時間割が開始された時に、チームメンバーにその旨を知らせる | チームメンバーの誰かが時間割を開始する(ユーザ操作起因) | 時間割を開始したユーザ以外のチームメンバー(複数人) | 不要 | 1日1回程度 | 必要 |
このユースケースに適したプッシュ通知の通知方式を選定します。
通知方式の比較
モバイル端末におけるプッシュ通知には、リモート通知とローカル通知の2種類が存在します。 また、モバイル端末のOSが持つ通知機能を用いず、アプリそのものに通知機能を持たせたり、既存のサービスを利用することで通知を送信する方式も存在します。
プッシュ通知で実現したいユースケースそれぞれについて、これらの通知方式のどれが適しているかを検討します。
それぞれの通知方式の概要は以下のとおりです。
リモート通知
各OSの提供元が提供するプッシュ通知送信用のサービスを介して、アプリがインストールされたユーザ端末へメッセージを送信する方式です。
端末にアプリをインストールして起動した際に、その端末とアプリケーションに対応する固有の登録トークンが生成されます。 その登録トークンを指定してリモート通知を送信することで、登録トークンに対応する端末のアプリへ通知が届きます。
リモート通知で送信した通知は、モバイル端末の各OSの通知領域に表示されます。 モバイル端末上でアプリケーションが起動していない状態でも通知を受信できます。 また、モバイル端末がオフライン状態で通知を受信できなくても、有効期間が切れるまでは次にオンライン状態となったときに通知を受信できます。
リモート通知は、サービス運営者からユーザへアプリの起動状態にかかわらず通知を届けたい場合に適しています。 具体的には、以下のような例が挙げられます。
- ユーザが依頼した処理の完了通知
- 確定したサービス利用料金のお知らせ
- ユーザの居住地域に応じて、その地域の天気予報メッセージを送信
ローカル通知
外部からメッセージを送信するのではなく、端末にインストールされたアプリから通知メッセージを送信する方式です。 その特性上、通知メッセージの送信先はその端末に限定され、他のユーザや他の端末へは通知を送信できません。 その代わりに、端末がオフライン状態であっても通知機能を利用できます。
ローカル通知もリモート通知と同様に、モバイル端末のOSの通知領域に表示され、 モバイル端末上でアプリケーションが起動していない状態でも通知を受信できます。
ローカル通知は、外部の情報が必要なくアプリ単体で通知の必要性やタイミングを判断できる場合に適しています。 具体的には、以下のような例が挙げられます。
- アプリ内で実施した非同期処理(ダウンロード処理など)の完了通知
- スケジュールアプリで予定を登録し、予定時刻の数分前にリマインドメッセージを表示
- 音楽プレイヤーアプリでバックグラウンドでの音楽再生中に、再生/停止などの操作を通知領域内で行うためのメッセージを表示
アプリへの通知機能の組み込み
AndroidやiOSが提供しているリモート通知機能は、ユーザになじみ深くモバイルアプリでは広く利用されています。 このリモート通知は端末側が受信可能な状態であればかなり高速に配信されるものの、リアルタイムでの通知の到達を保証するものではありません。 また、リモート通知にはデータサイズや送信レートの上限が存在するため、巨大なデータを含む通知を送信したり、高頻度で通知を送信する必要がある場合にも適していません。 許容されるレイテンシに上限がある場合や、高頻度でデータの送受信を行う必要がある場合は、自前でアプリに通知機能を組み込むことも選択肢に入ります。
リアルタイムな通知を実現する方式の1つとして、WebSocketを用いた通知が挙げられます。 WebSocketを用いることで、データに更新があった際にすぐに受信してアプリ内の描画内容を更新できます。 ただし、アプリが前面またはバックグラウンドで稼働した状態である必要があります。
WebSocketを用いた通知は、リアルタイムで高頻度に情報を受信したり、クライアントとサーバで双方向の通信をしたい場合に適しています。 具体的には、以下のような例が挙げられます。
- チャットアプリで受信したメッセージをリアルタイム表示し、こちらからもメッセージを送信
- 宅配アプリで配送中のドライバーの位置をリアルタイムで更新
WebSocketを直接利用するほかに、Firebase Cloud Firestoreのようなリアルタイムな更新データの読み取りに対応したサービスを利用することでも同様の効果が期待できます。
その他の既存サービスを用いた通知
OSの通知機能の利用やアプリへの通知機能の組み込みにこだわらず、既存のサービスを利用する形でメッセージを届けることも選択肢の1つです。 SMSやEmailといった既存のサービスを利用することで、アプリをインストールしていないユーザにもメッセージを届けることができます。 また昨今では、LINE通知メッセージを利用してメッセージを届けるケースも出てきています。
今回採用する通知方式
時間割の開始通知のユースケースでは、誰かが時間割を開始した時に、そのチームに所属する全てのユーザに対してその旨を通知します。 チームに所属する他のユーザへ通知を送信する必要があるため、ローカル通知は利用できません。 アプリを起動していないユーザにも伝えたい通知内容であるため、WebSocketを用いた通知も今回は除外します。 また、SMSやEmailといった別のサービスの通知として表示するよりは、このアプリの通知として通知領域に表示し、通知からアプリを直接起動できるようにしたいです。 そのため今回はリモート通知を採用します。
このアプリには他のプッシュ通知のユースケースは存在しないため、 利用する通知方式はリモート通知のみとなります。
リモート通知の送信に用いるサービスの選定
リモート通知の送信には、各OSの提供元が提供するプッシュ通知送信用のサービスを直接利用する方式の他に、 それらのサービスを統合管理するサービスを介して利用する方式もあります。
それぞれの方式の概要は以下のとおりです。
各OSの提供元が提供するプッシュ通知送信用のサービスを直接呼びだす方式
モバイル端末で利用されているAndroid, iOSなどの各OSの提供元は、それらのOSの端末へプッシュ通知を送信するためのサービスを提供しています。 例えばAndroidやiOS端末では、以下のサービスを介してプッシュ通知が送信されます。
- Android: Android Transport Layer (ATL)
- iOS: Apple Push Notification service (APNs)
Android端末に向けてプッシュ通知を送信するATLについては、直接このサービスを呼びだすのではなく、 Firebase Cloud Messaging (FCM)のAPIを介して利用することになります。
Android端末宛ならFCM、iOS端末宛ならAPNsのAPIを直接呼びだすことで、各OS特有の細かいオプションも含めた全ての機能を利用してプッシュ通知を送信できます。 一方でAPIを呼び分けるためには送信先の端末のOSが何なのかを自前で識別し、それぞれのOSにあった適切なサービスを呼びだす必要があります。
FCMを介して各OSのプッシュ通知送信用サービスを利用する方式
FCMはAndroid端末に向けたプッシュ通知の送信だけでなく、APNsを介したiOS端末向けのプッシュ通知送信やWeb Pushにも対応しています。 対応するOSであればどのOSの端末宛であっても全てFCMに任せることができ、端末のOSが何であるかをプッシュ通知を送信するサーバ側で意識する必要がなくなります。 各OS特有の細かいプッシュ通知のオプションについても、その大部分に対応しています。
またFCMは、指定したデバイスへ通知を送信するだけでなく、デバイスグループ単位やトピック単位で通知を送信する機能も提供しています。 こうした機能を用いることで、特定の条件を満たす複数ユーザへのプッシュ通知送信を管理しやすくなります。
FCMはAndroid端末へのプッシュ通知を行う場合は直接または間接的に必ず利用するサービスであり、 契約するサービス数が増えたり追加の費用が発生するわけではないことも管理上のメリットとなります。
その他のサービスを介して各OSのプッシュ通知送信用サービスを利用する方式
FCM以外にも、各OSの端末に向けたプッシュ通知や、EmailやSMSなどのその他チャネルを介した通知を統合管理できるサービスが各社から提供されています。 例えば以下のようなサービスが存在します。
- Amazon Pinpoint
- Azure Notification Hubs
こうしたサービスでは単純に通知を送信するだけでなく、例えばマーケティングメッセージ送信の支援や効果の測定など、さまざまな付加価値が追加されています。 また、Kindle端末などFCMが対応していないOSもサポートしているサービスもあります。
単純にプッシュ通知を送信するだけの場合と比べて追加の費用はかかりますが、 提供されている付加価値がユースケースとうまく合致する場合は有力な選択肢となり得ます。
今回採用するリモート通知送信用サービス
このアプリのサポート対象OSはAndroid、iOS、iPadOSであり、いずれもFCMを介したプッシュ通知の送信が可能です。
このアプリでは、プッシュ通知送信処理の実装をシンプルなものにするため、 直接各OS向けのプッシュ通知送信サービスを利用するのではなく、FCMを介してリモート通知を送信します。 FCMはこのアプリのユースケースに十分な機能を備えているため、追加費用のかかるその他のサービスは採用しません。
リモート通知の宛先指定方式
FCMを介してリモート通知を送信する場合、デバイス指定での送信の他に、デバイスグループ指定、トピック指定での送信もできます。 それぞれの概要は以下のとおりです。
デバイス指定
指定したデバイスに対してリモート通知を送信します。
デバイス指定のリモート通知は、特定のユーザを対象とした内容のメッセージを送信する場合に適しています。 具体的には、以下のような例が挙げられます。
- ユーザが依頼した処理の完了通知
- 確定したサービス利用料金のお知らせ
FCMを利用したデバイス指定での送信では、同一メッセージを一度に最大500デバイスに対して送信できます。
デバイスグループ指定
特定のデバイスグループに参加している全デバイスへリモート通知を送信します。
デバイスグループへ送信するためには、事前にデバイスグループを作成し、デバイスグループに端末の登録トークンを登録しておくことが必要です。 この処理はFirebase Admin SDKを利用する必要があるためクライアントアプリ側では実施できず、バックエンドサーバ側で端末の登録処理を行う必要があります。
デバイスグループに登録できるデバイスの最大数は20に制限されています。 そのためグループに登録するデバイス数が20を超えることが予想される用途には適していません。 作成可能なデバイスグループの上限については、公式ドキュメント内では特に言及されていませんでした。
端末グループに送信するというドキュメントは存在するものの、 デバイスグループの作成やデバイス登録・削除は2021年12月時点ではHTTP v1 API以前の古いAPIでしか対応していないようです。 Firebase Admin Java SDKのIssue内のコメントでは、 FCMチームでデバイスグループに相当するプライベートトピックの機能に取り組んでいると言及されています。 デバイスグループは今後廃止される可能性もありそうです。
トピック指定
特定のトピックを購読している全デバイスへリモート通知を送信します。
トピック指定のリモート通知では、単一のトピックへの送信だけではなく、トピックAとトピックBを両方購読していることなども条件として指定できます。 また、トピックの購読処理はバックエンドサーバだけでなくクライアントアプリからも行えます。
トピック指定のリモート通知は、大量の送信先へ一括でメッセージを送信する場合に適しています。 具体的には、以下のような例が挙げられます。
- ユーザの居住地域に応じて、その地域の天気予報メッセージを送信
- ユーザが興味のあるテーマを設定し、運営者からテーマに応じたメッセージを送信
一方で、FCMのドキュメント内では「レイテンシではなくスループットに対して最適化されます」と記載されています。 通知受信までのレイテンシを重視する場合はデバイス指定での送信が適しています。
FCMでは1アプリあたりのトピック数上限は2000に制限されています。 そのため2000トピックを超えることが予想される用途には適していません。 1トピックあたりの購読者数には制限はありません。
今回採用する宛先指定方式
まず、デバイスグループは将来的な動静が見通せないため、今回は採用しないことにします。
トピック指定での送信の場合、1アプリあたりで作成可能数なトピック数は2000までです。 時間割の開始通知のユースケースでチームをトピックとして扱った場合、チーム数が2000を超えてしまうと破綻するため採用できません。
そのため、今回は各ユーザの各デバイスの登録トークンをバックエンドサーバ上で管理し、 チームに所属する各ユーザの各デバイスに向けて、個別にリモート通知を送信するものとします。
個別送信と一括送信
FCMでは先述のとおり、デバイス宛、デバイスグループ宛、トピック宛の3種類の宛先指定方式があります。 FCMではこれらの宛先へ1件ずつメッセージを個別送信するだけでなく、複数の宛先へ一括送信する機能も提供されています。
FCMにおける一括送信には、 同一のメッセージを複数の宛先へ同時送信するマルチキャスト送信と、 異なるメッセージを複数の宛先へ同時送信するバッチ送信があります。
マルチキャスト送信では、宛先に複数のデバイストークンを指定することで同一のメッセージを複数のデバイスへ同時に送信できます。 一度のリクエストで最大500デバイスまでを宛先に指定できます。
バッチ送信では、異なるメッセージを1回のリクエストで同時に送信できます。 個々のメッセージの内容は個別に指定できます。 また宛先もデバイス宛、デバイスグループ宛、トピック宛のいずれでも構いません。 1回のリクエストで最大500件までのメッセージを送信できます。
時間割の開始通知では、複数の宛先に同一のメッセージを送信します。 そのため、マルチキャスト送信を用いて複数の宛先へ同時にメッセージを送信します。 宛先が500デバイスを超える場合は、複数回のリクエストに分けて送信します。
決定
このアプリでは、以下のユースケースそれぞれに対して以下のプッシュ通知方式を採用します。
- 時間割の開始通知
- 通知方式:リモート通知
- 宛先指定方式:デバイス指定
- 送信方式:マルチキャスト送信
このアプリにおけるリモート通知の送信は、全てFCMを介して送信するものとします。