Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Firebase Cloud Messagingにおける 通知速度のボトルネックの調査と改善

Avatar for ntsk ntsk PRO
November 13, 2025

Firebase Cloud Messagingにおける 通知速度のボトルネックの調査と改善

Avatar for ntsk

ntsk PRO

November 13, 2025
Tweet

More Decks by ntsk

Other Decks in Programming

Transcript

  1. • https://firebase.google.com/docs/cloud-messaging • Google が提供する無料のプッシュ通知サービス • 下記の2つの主要なコンポーネントを提供 ◦ FCMバックエンド ▪

    メッセージリクエストからメッセージのデータを生成するバックエンドサーバー の提供 ▪ Firebase Admin SDK(Node, Java, Python, C#, Go)やFCM APIを利 用したFCMサーバーとの対話 ◦ FCMクライアント ▪ iOS, Android, Web, Flutter, Unity, C++などに対応 Firebase Cloud Messaging 7
  2. • トークンベース ◦ 配信したいデバイスに対してFCMトークンを指定して送信する ◦ 呼び出しごとに500個までトークン指定が可能 • トピックベース ◦ 特定トピックにオプトインした複数デバイスにメッセージを送信する

    ◦ トピックの上限は2000まで • デバイスグループベース (※Admin SDKでは未対応) ◦ グループ毎に発行したキーをベースに送信する ◦ 1つのキーに紐付けられるトークンは20まで メッセージ配信方法の種類 9
  3. 特定のデバイスへ送信 registration_token = 'YOUR_REGISTRATION_TOKEN' message = messaging.Message( data={ 'score': '850',

    'time': '2:45', }, token=registration_token, ) response = messaging.send(message) registration_tokens = [ 'YOUR_REGISTRATION_TOKEN_1', # ... 'YOUR_REGISTRATION_TOKEN_N', ] message = messaging.MulticastMessage( data={'score': '850', 'time': '2:45'}, tokens=registration_tokens, ) response = messaging.send_each_for_multicast(message) 複数デバイスへ送信 トークンベースの実装例 (Python) 10
  4. 特定のトピックに対してトークンを購読/解除 トピックベースの実装例 (Python) registration_tokens = [ 'YOUR_REGISTRATION_TOKEN_1', # ... 'YOUR_REGISTRATION_TOKEN_n',

    ] # Subscribe the devices corresponding to the registration tokens to the topic response = messaging.subscribe_to_topic(registration_tokens, topic) # Unsubscribe the devices corresponding to the registration tokens to the topic response = messaging.unsubscribe_from_topic(registration_tokens, topic) 11
  5. トピックを購読しているデバイスへ送信 トピックベースの実装例 (Python) topic = 'highScores' message = messaging.Message( data={

    'score': '850', 'time': '2:45', }, topic=topic, ) # Send a message to the devices subscribed to the provided topic. response = messaging.send(message) 12
  6. デバイスグループを作成 デバイスグループベースの実装例 (HTTPS) POST https://fcm.googleapis.com/fcm/notification Content-Type:application/json access_token_auth: true Authorization: Bearer

    ya29.ElqKBGN2Ri_Uz...HnS_uNreA project_id:SENDER_ID { "operation": "create", "notification_key_name": "appUser-Chris", "registration_ids": ["bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "cR1rjyj4_Kc:APA91bGusqbypSuMdsh7jSNrW4nzsM...", ... ] } { "notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ" } REQUEST RESPONSE 13
  7. トークン登録 ~配信のフロー 配信ツール アプリAPI 🔔 ③Push通知 送信指示 ④Push通知 送信指示 ⑤Push通知

    送信 ①通知許諾・トークン登録リクエスト ②トピック購読トー クン登録 Firebase 17
  8. 自社APIが通知を送信した時刻 配信ツール アプリAPI 🔔 ③Push通知 送信指示 ④Push通知 送信指示 ⑤Push通知 送信

    ①通知許諾・トークン登録リクエスト ②トピック購読トー クン登録 Firebase 22
  9. Firebaseサーバーが通知を送信した時刻 配信ツール アプリAPI 🔔 ③Push通知 送信指示 ④Push通知 送信指示 ⑤Push通知 送信

    ①通知許諾・トークン登録リクエスト ②トピック購読トー クン登録 Firebase 24
  10. Firebaseサーバーが通知を送信した時刻 BigQuery データエクスポートで調査に活用できるフィールド (抜粋) event_timestamp TIMESTAMP サーバーにより記録されたイベントのタイムスタンプ。 app_name STRING Android

    アプリのパッケージ名または iOS アプリのバンドル ID。 topic STRING メッセージが送信されたトピックの名前(該当する場合)。 event STRING • MESSAGE_ACCEPTED: メッセージは FCM サーバーによって受信され、リクエストは有効です。 • MESSAGE_DELIVERED: メッセージはデバイス上のアプリの FCM SDK に配信されました。デフォルトで は、このフィールドは伝播されません。有効にするには、 setDeliveryMetricsExportToBigQuery(boolean) の手順に従ってください。 • etc… analytics_label STRING メッセージの送信時にアナリティクス ラベルを設定して、そのメッセージをアナリティクス用としてマークできます。 https://firebase.google.com/docs/cloud-messaging/understand-delivery?platform=ios#what-data-exported 27
  11. Firebaseサーバーが通知を送信した時刻 SELECT TIMESTAMP_DIFF( MAX(delivered_time), MIN(accepted_time), MILLISECOND ) AS latency_ms FROM

    ( SELECT event_timestamp AS accepted_time FROM `project ID.firebase_messaging.data` WHERE _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD') AND message_id = 'your message id' AND instance_id = 'your instance id' AND event = 'MESSAGE_ACCEPTED' ) sent CROSS JOIN ( SELECT event_timestamp AS delivered_time FROM `project ID.firebase_messaging.data` WHERE _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD') AND message_id = 'your message id' AND instance_id = 'your instance id' AND (event = 'MESSAGE_DELIVERED' ) delivered; 遅延を調査するクエリの例 28
  12. トランスポート時の遅延有無 配信ツール アプリAPI 🔔 ③Push通知 送信指示 ④Push通知 送信指示 ⑤Push通知 送信

    ①通知許諾・トークン登録リクエスト ②トピック購読トー クン登録 Firebase 29
  13. トランスポート時の遅延有無 • AndroidのみFirebase Cloud Messaging Data API を利用すること で、Android SDKにおける配信指標を確認可能

    ◦ https://firebase.google.com/docs/cloud-messaging/understand-deli very#message-delivery-reports ◦ ただしレポートの反映まで最大24hの遅延がある 30
  14. トランスポート時の遅延有無 { "appId": "1:23456789:android:a93a5mb1234efe56", "date": { "year": 2021, "month": 1,

    "day": 1 }, "analyticsLabel": "foo", "data": { "countMessagesAccepted": "314159", "messageOutcomePercents": { "delivered": 71, "pending": 15 }, "deliveryPerformancePercents": { "deliveredNoDelay": 45, "delayedDeviceOffline": 11 } } 31
  15. アプリが通知を受け取った時刻 配信ツール アプリAPI 🔔 ③Push通知 送信指示 ④Push通知 送信指示 ⑤Push通知 送信

    ①通知許諾・トークン登録リクエスト ②トピック購読トー クン登録 Firebase 33
  16. 端末上で通知が表示された時刻 配信ツール アプリAPI 🔔 ③Push通知 送信指示 ④Push通知 送信指示 ⑤Push通知 送信

    ①通知許諾・トークン登録リクエスト ②トピック購読トー クン登録 Firebase 36
  17. • V1 / V2の送信を分けるには、conditionを利用。 ◦ 'TopicV2' in topics なら V2に送信

    ◦ !('TopicV2' in topics) && 'TopicV1' in topics ならV1に送信とする ◦ https://firebase.google.com/docs/cloud-messaging/send-topic-mess ages トピックを段階的に移行 49