$30 off During Our Annual Pro Sale. View Details »

FCMを使った用途に合わせたPush通知設計 / Push notification architecture design according to the use case using FCM

佐藤さん
February 07, 2019

FCMを使った用途に合わせたPush通知設計 / Push notification architecture design according to the use case using FCM

DroidKaigi 2019 2019/02/07 14:00 - 14:30 Room 6

Push通知はアプリ利用者に対する何らかのイベントの発生、フォローしている人の新着情報、あるいはサービスやアプリ内機能の宣伝など多岐に渡る用途で使われています。
Push通知の開発を始めると、サーバーサイドですべての通知を制御するかアプリ側で通知をフィルタリングするか、あるいは高速に通知を配信するためにはどうすればいいかなど、様々な悩みが出てきます。
Push通知は幅広い用途に使われるため、こうすればすべて解決!という設計はなく、ケースバイケースで適した設計を考えなければいけません。

本セッションでは、Firebase Cloud Messaging(FCM)を利用して、用途にあわせた設計をアプリだけではなくサーバーサイドも含めて考察します。
まずはFCMでできることをおさらいした上で、具体的な設計の話に入ります。
また、実際の例として発表者が業務で開発しているアプリにおけるPush通知の設計も紹介します。

■ 受講対象者
FCMでできることを知りたい方やPush通知をどのように実装するか悩んでいる方を対象としています。

佐藤さん

February 07, 2019
Tweet

More Decks by 佐藤さん

Other Decks in Programming

Transcript

  1. FCMを使った
    用途に合わせたPush通知設計
    pixiv Inc.
    Koji OKADA
    2019.2.7

    View Slide

  2. 自己紹介
    ● ピクシブ株式会社 新技術プロジェクト エンジニア
    ● 岡田 康治 / Koji OKADA
    ● Twitter: @SuperSatoSan
    ● Android / バックエンド / フロントエンド / Unity
    ● 今日はAndroidエンジニアとして来ました
    2

    View Slide

  3. Push通知は様々な用途に使える
    ● 個別のユーザーに対するイベントが発生したことを通知する
    ● 多数のユーザーに対して新機能やキャンペーンがあることを通知する
    3

    View Slide

  4. 考えなきゃいけない要件はたくさん
    ● どのくらいの頻度で送る?
    ● 送信対象ユーザーの規模は?
    ● どのぐらいの遅延が許される?
    ● 送信するメッセージの内容は?
    ● いつリリースする?
    ● 開発体制は?
    ● etc
    4

    View Slide

  5. Firebase Cloud Messaging(FCM)
    ● 各プラットフォームへのPush通知送信を統一出来る
    メッセージングソリューション
    ● ピクシブでも様々なプロダクトで活用されている
    ● 本セッションはFCMを使うことを前提に話をする
    5

    View Slide

  6. FCMでも全てを解決できる方法はない
    ● 100万ユーザーに同じ内容を一つずつ送ったら……
    ● ユーザー固有の内容を全ユーザーにまとめて送ったら……
    ● 用途に適した仕組み = 設計を考える必要がある
    6

    View Slide

  7. 今日の内容
    ● 設計する際に拠り所となる考え方
    ● pixivアプリを例に何を考えて設計を決めていったか
    ● 明日使えるかも知れない技術的な知見
    7

    View Slide

  8. 設計を考える拠り所
    ● 制約を満たすように設計を考えると選択肢はほとんど無くなる
    ● FCMで出来ることは制約
    ● 実現する機能の要件も制約
    8

    View Slide

  9. FCMに出来ること
    9
    サービスサーバー
    アプリ
    FCMサーバー
    2. 通知の送信をリクエストする
    3. 通知データを処理する
    1. 通知対象をサーバーサイドで把握する
    ※: FCMサーバーとの区別のためサービスのためのAPIサーバーやバッチサーバーをまとめてサービスサーバーと呼ぶ

    View Slide

  10. 通知対象をサーバーサイドで把握する
    ● Push通知を送信する端末をサービスサーバーが認識する手段の選択肢
    A. デバイストークンをサービスサーバーへ送信する
    B. トピックをSubscribeする
    ○ 少量の送信速度で劣る代わりに大量の通知の送信に向いている
    C. サービスサーバーでデバイスグループを作成する
    D. サービスサーバーでトピックにサブスクライブさせる
    ○ 対象端末のデバイストークンが必要
    10

    View Slide

  11. 通知の送信をリクエストする
    ● サービスサーバーからFCMサーバーへPush通知を送る手段の選択肢
    A. HTTP v1 API
    B. レガシーHTTPサーバー
    ○ 現在はHTTP v1 APIの利用が推奨されている
    C. レガシーXMPPサーバー
    ○ HTTPと比べて非同期で複数の通知を連投出来るのがメリット
    D. FirebaseAdminSDK
    ○ Node, Java, Python, Goで使える
    ● 表示するメッセージ以外にアプリ側で処理するためのパラメータを送れる
    11

    View Slide

  12. FCMから通知されたデータを表示する
    ● FCMサーバーから届いたPush通知をユーザーに表示する手段の選択肢
    A. 通知に設定されているタイトルや本文をそのまま表示
    B. コールバックで独自にメッセージを組み立てることもできる
    ○ 通知に含めたパラメータを利用
    ○ 通知ドット(バッジ)やアプリ固有の処理もこれでやる
    12

    View Slide

  13. 設計の実例
    13

    View Slide

  14. ● 創作に特化したライブ配信サービス
    ● 最大4人同時に配信可能
    ● コミュニケーションしながら
    創作活動を楽しめる
    ● pixivアプリはpixiv Sketch LIVEの
    視聴機能を提供している
    題材: pixiv Sketch LIVE
    14

    View Slide

  15. 例にする通知機能
    ● フォローユーザーがpixivSketch LIVEで配信を開始した通知
    ● フォローしているユーザーが配信を開始したときにPush通知がくる
    ● 以降のスライドではライブ開始通知と呼ぶ
    15
    配信開始!
    ○○さんが
    ライブ中!

    View Slide

  16. 既存のPush通知基盤
    ● 基盤がこの開発以前から存在していた
    ● 提供する通知機能
    ○ 誰かにフォローされた
    ○ 自分の作品をすき!された
    ○ etc
    ● 一つのイベントで
    一人への通知しか生じない
    ● まずはこの設計を紹介
    16
    サービスサーバー
    アプリ
    FCMサーバー
    ?

    View Slide

  17. 通知対象をサーバーサイドで把握する
    A. デバイストークンをサービスサーバーへ送信する
    B. トピックをサブスクライブする
    ○ ユーザー毎に自分専用のトピックをサブスクライブしている
    C. サービスサーバーでデバイスグループを作成する
    D. サービスサーバーでトピックにサブスクライブさせる
    17

    View Slide

  18. 通知対象をサーバーサイドで把握する
    ● DBでデバイストークンを管理したくない
    ● Push通知の送信から大抵は数秒、遅くとも数分以内に受信できている
    ● 即時に通知を受信する必要のある状況では選択しにくい方法
    ○ pixivアプリではそこまでクリティカルではない
    18

    View Slide

  19. 通知の送信をリクエストする
    A. HTTP v1 API
    B. レガシーHTTPサーバー
    C. レガシーXMPPサーバー
    ○ 各種イベント等が発生したら通知キューに通知をためる
    ○ バッチサーバーで送信バッチを回して送信している
    ○ 深夜帯に送らない等のフィルタリングはサービスサーバーの責務
    D. FirebaseAdminSDK
    19

    View Slide

  20. 通知の送信をリクエストする
    ● pixivのサービスサーバーはPHPで実装されているのでSDKは選べない
    ● HTTP v1 API以前に実装されたのでレガシーHTTPかXMPPになる
    ● ユーザー起因のイベントで通知が発生する
    ○ 単位時間あたりの送信能力を高くしたい
    20

    View Slide

  21. 通知されたデータを処理する
    A. 通知に設定されているタイトルや本文をそのまま表示
    B. コールバックで独自にメッセージを組み立てる
    21

    View Slide

  22. 通知されたデータを処理する
    ● Android・iOS共にPush通知の基本的な使い方
    ● アプリのリリース無しで文言の改善が出来る
    22

    View Slide

  23. ● アプリ
    ○ トピックのサブスクライブ
    ○ Push通知はそのまま表示
    ○ 通知を受けたときの処理
    アプリ・サービスサーバーの責務分担
    23
    ● サービスサーバー
    ○ 通知のキューイング
    ○ 通知メッセージの生成
    ○ 通知のフィルタリング
    ● アプリは通知の種類ごとに必要な特別な処理を実装するだけ
    ● その分責務がサービスサーバーに寄せている
    ● 大抵はサービスサーバーだけでやれば良いので考えることが少ない

    View Slide

  24. ライブ開始通知の設計
    24
    配信開始!
    ○○さんが
    ライブ中!

    View Slide

  25. 設計のために制約を整理する
    25
    ● 設計を絞り込むために制約を考える
    ○ どのくらいの頻度で送る?
    ○ 送信対象ユーザーの規模は?
    ○ どのぐらいの遅延が許される?
    ○ 送信するメッセージの内容は?
    ○ いつリリースする?
    ○ 開発体制は?

    View Slide

  26. どのくらいの頻度で送る?
    ● ユーザーの配信開始タイミングは制御できない
    ● 最も増える夜の時間帯に毎分数人が開始することを想定
    ● イベントが発生する頻度はこれまでと比べて大きな差はない
    26
    制約
    ● 特になし

    View Slide

  27. 送信対象ユーザーの規模は?
    ● 最大クラスのユーザーになると数十万人に送信することになる
    ● これまでは1イベントあたり1件だったが、それが膨大な量に増える
    27
    制約
    ● 一回のイベントあたりの通知件数が大幅に増加

    View Slide

  28. どのぐらいの遅延が許される?
    ● 通知の数が膨大になることで遅延が無視できなくなってくる
    ● 最大クラスのユーザーに配信開始から15分程度で送信完了したい
    ● 10万フォロワー規模の配信を10分で捌くのをパフォーマンス目標に設定
    28
    制約
    ● 許容出来る通知の遅延に限度がある

    View Slide

  29. 送信するメッセージの内容は?
    ● 全てのフォロワーに対して共通のメッセージが送信される
    ● これまでと同様の仕組みで問題なし
    ● 未対応バージョンのアプリにPush通知を送信すると
    タップしても何も反応しない通知が出る
    29
    制約
    ● 未対応バージョンに影響しないように送信する

    View Slide

  30. いつリリースする?
    ● 長くても3ヶ月程度でリリースしてほしい
    30
    制約
    ● 長くて3ヶ月程度でできる仕様に留めないといけない

    View Slide

  31. 開発体制は?
    ● 専任する開発者は自分ひとり
    ● すでに個別ユーザーにpush通知を送信する基盤は存在する
    ● アプリ開発メンバーはpixiv Sketch LIVE自体の視聴機能に集中
    ● アプリ側の対応も必要な場合は自分で行う必要あり
    31
    制約
    ● 一人で開発完了できる仕様に留めないといけない

    View Slide

  32. 設計への影響のまとめ
    ● 一回のイベントあたりの通知件数が大幅に増加
    ○ 送信の遅延が無視できなくなる
    ● 非対応バージョンのユーザーにPush通知を飛ばさないようにする
    ● アプリ・サーバーサイド含めて長くて一人で3ヶ月程度で完了できる
    32

    View Slide

  33. 1. 通知の遅延が無視できない
    A. 送信バッチを並列化する
    ○ 現状の発展形で実現可能
    B. フォロワー向けのトピックを作る
    ○ 新しいトピックをSubscribeする変更がアプリに必要
    ○ 通知を出すかどうかの判断の責務がアプリ側に移る
    33

    View Slide

  34. 送信バッチを並列化する
    ● 1デバイスずつ送信する設計は変えずに並列化
    ● XMPPの送信能力的には並列化だけでも目標を達成できる
    34
    送信バッチ
    送信バッチ
    送信バッチ
    送信バッチ
    FCMサーバー
    アプリ アプリ アプリ

    View Slide

  35. フォロワー向けのトピックを作る
    ● 新しいトピックをSubscribeする変更がアプリに必要
    ● 通知を出すかどうかの判断の責務がアプリ側に移る
    35
    FCMサーバー
    フォロワー向け
    トピック
    アプリ アプリ アプリ
    サービスサーバー
    送信バッチ

    View Slide

  36. 並列化を選択
    ● 理想は「フォロワー向けのトピックを作る」方式
    ● ただし一部の通知だけが別のルールで設計されていると混乱する
    ● やるなら全部改修すべき
    ● 一人でサービスサーバーに加えて
    Android、iOSまで作業するのは時間がかかる
    36

    View Slide

  37. 2. 非対応バージョンに通知を送らない
    1. 最近使ったアプリのバージョンを
    DBに記録してフィルタリング
    2. ログベースでBigQueryで送信する対象をフィルタリング
    37

    View Slide

  38. サービスサーバー
    アプリのバージョンをDBに記録する
    38
    FCMサーバー
    APIサーバー
    アプリ
    送信バッチ
    サーバー
    DB
    フィルタリング時に
    バージョンも条件にする
    使ってるアプリバージョンを
    報告する

    View Slide

  39. BigQueryでフィルタリング
    39
    BigQuery
    pixivのログ基盤
    送信バッチ
    FCMサーバー
    毎日一回
    特定バージョン以上を使ってるユー
    ザーのリストを更新
    送信前に問い合わせてフィルタリング

    View Slide

  40. BigQueryでフィルタリング
    ● 費用は¥1000/月ぐらいで済んでいる
    ● 特定バージョン以上を使ってるユーザーのリストの更新が一番コストが高い
    ○ 前日までのリストと当日分のログを合成してコストダウン
    ○ ログから不要なデータを落としたテーブルにしている
    ● バッチ実行時の問い合わせは最小限のデータに対する
    SELECTなので安い
    40

    View Slide

  41. BigQueryフィルタリングを選択
    ● 最近使ったバージョンの記録は作業時間がかさむと判断した
    ○ DBにテーブルを追加するためのスキーマレビュー
    ○ アプリを改修も必要
    ○ すでにログに必要な情報があるのでメリットも薄い
    ● BigQuery方式はそのあたりの悩みどころを全部飛ばして実装出来るが魅力
    ○ 金額的にも十分安い
    41

    View Slide

  42. 最終的な責務分割
    ● アプリ
    ○ トピックのサブスクライブ
    ○ Push通知はそのまま表示
    ○ 通知を受けたときの処理
    42
    ● サービスサーバー
    ○ 通知のキューイング
    ○ 通知メッセージの生成
    ○ 通知のフィルタリング
    変更なし

    View Slide

  43. 次に改善するとしたら
    ● フォロワー向けの通知は大量の通知が発生して遅延する
    ● クライアントでフォロワー用トピックをサブスクライブするのが理想
    ● 一部だけ別のルールの設計にならないように通知機能全体を改修したい
    43
    ● アプリ
    ○ トピックのサブスクライブ
    ○ Push通知はそのまま表示
    ○ 通知を受けたときの処理
    ○ 通知のフィルタリング
    ● サービスサーバー
    ○ 通知のキューイング
    ○ 通知メッセージの生成

    View Slide

  44. まとめ
    ● あらゆる用途に最適な設計は存在しない
    ● 制約を満たすように設計を考えると自然と選択肢が絞られる
    ● 制約は開発する機能の仕様だけではない
    ● 開発体制の都合も含めて制約になる
    44

    View Slide