kakakakakku blog

Weekly Tech Blog: Keep on Learning!

FCM (Firebase Cloud Messaging) で Instance ID API を使ってトピックをサブスクライブする

最近 Firebase を検証している.今回は mBaaS としての Firebase ではなく,プッシュ通知基盤としての Firebase を検証していて,学んだことをまとめておこうと思う.Firebase には他にも Analytics や Functions や Remote Config などなど,機能がたくさんあり,使っていて凄くワクワクする.

前提

前提として,動作検証をするアプリに Firebase を導入して,端末トークンを取得できるようにしておくことと,プッシュ通知を受け取れるようにしておく必要がある.この部分は割愛するが,詳しくは以下のドキュメントに載っている.

2種類ある Firebase のプッシュ通知

Firebase のプッシュ通知は,大きく2種類ある.このあたりの前提知識がないと,ドキュメントを読んでも混乱してしまうと思う.Firebase Notifications というのは,Firebase の管理画面からプッシュ通知を送る方式で,FCM というのは,HTTP 経由でプッシュ通知を送る方式のことを意味する.

  • Firebase Notifications
  • FCM (Firebase Cloud Messaging)
    • Notification Message
    • Data Message

その他の細かな差異に関しては,Firebase の FAQ に詳しく載っている.

Cloud Messaging: What's the difference between the Notifications composer and Cloud Messaging?
https://firebase.google.com/support/faq/

また,FCM には Notification Message と Data Message という,2種類のメッセージタイプがある.簡易的なプッシュ通知を実現する場合は Notification Message を使えば良いが,Notification Message と Data Message を組み合わせて使うこともできる.また,アプリの状態(フォアグラウンド/バックグラウンド)によっても挙動が異なるため,詳細はドキュメントを参照で.

ターゲット

プッシュ通知を送るターゲットは大きく3種類ある.

  • ユーザーセグメント ... 言語 / バージョン / ユーザープロパティなどを AND / OR 演算した集合体
  • トピック ... 任意のグループ
  • 端末 ... 特定の端末(登録トークン指定)

トピック

今回はトピックを検証した.トピックとは任意のグループのようなもので,トピックの中に端末(登録トークン)を紐付けていく.これを「サブスクライブ」と呼ぶ.ドキュメントでは「天気予報アプリで,荒天警報の通知を受けたい人」というトピックが紹介されていた.このように任意のグループを作成することができる.また,個数上限のあるユーザーセグメントとは異なり,トピックは無制限なので,大量に作っても問題が無さそう.

サブスクライブをする場合,以下のドキュメントに載っているような実装をする.具体的には subscribeToTopicunsubscribeFromTopic を呼び出す.なお,実行時にトピックが存在しない場合は,自動的にトピックも作成される.ただし,トピックが作成されるまでに最大1日待つ必要がある.今回トピックを数個作成してみて,大体4時間程度で作成されたが,それでも結構な時間を待つ必要があることには変わりがないと思う.

f:id:kakku22:20170512123010p:plain

Firebase の管理画面からプッシュ通知を送る

Firebase の管理画面で,Notifications のメニューを選択して送信するだけなので,割愛する.

curl で FCM (Firebase Cloud Messaging) のプッシュ通知を送る

curl で FCM のプッシュ通知を送る場合,以下のように実現できる.FIREBASE_SERVER_KEY には管理画面の設定ページから取得したサーバーキーを設定しておく必要がある.

$ FIREBASE_SERVER_KEY=''
$ curl --header "Authorization: key=${FIREBASE_SERVER_KEY}" \
  --header "Content-type: application/json" \
  https://fcm.googleapis.com/fcm/send \
  -d @firebase.json

リクエストとして送るパラメータ ( firebase.json ) は以下のように書く.今回はテスト用に test トピックを事前に用意した.表記としては /topics/test のように書く.プッシュ通知のタイトルと本文もそれぞれ定義する.

{
    "to": "/topics/test",
    "priority": "high",
    "notification": {
        "title": "title",
        "body": "body"
    }
}

Instance ID API で登録トークンを操作する

Google が提供している Instance ID API を使うと,HTTP 経由で登録トークンの情報を取得したり,トピックをサブスクライブすることができる.最初はネイティブじゃないとできないと思っていたので,この API を発見したときは驚いた.

ちなみに Instance ID API の文脈で言うと「インスタンス ID」という名称に変わるが,結局のところ,今まで紹介してきた「登録トークン」と同じもので,正確に言えば,「インスタンス ID」では iOS と Android 以外に Chrome も識別することができるという点が違うと思われる.当然ながら,プライバシーの観点で「インスタンス ID」も「登録トークン」もリフレッシュもできる.今回は「登録トークン」の表記で統一する.

登録トークンの情報を取得する API

IID_TOKEN には nKctODamlM4:CKrh_PC8kIb7O...clJONHoA などの登録トークン(正確には152文字?)を指定する.以下のエンドポイントを叩くと,登録トークンがサブスクライブしているトピックの一覧や,ネット接続タイプ WIFI or MOBILE,プラットフォームなどを取得することができる.

$ FIREBASE_SERVER_KEY=''
$ IID_TOKEN=''
$ curl --header "Authorization: key=${FIREBASE_SERVER_KEY}" \
  "https://iid.googleapis.com/iid/info/${IID_TOKEN}?details=true" | jq .
{
  "applicationVersion": "0.0.1",
  "connectDate": "2017-05-09",
  "application": "com.example",
  "scope": "*",
  "authorizedEntity": "111111111111",
  "rel": {
    "topics": {
      "test": {
        "addDate": "2017-05-09"
      }
    }
  },
  "connectionType": "WIFI",
  "platform": "IOS"
}

登録トークンを指定してトピックをサブスクライブする API

以下のエンドポイントを叩くと,登録トークンを指定してトピックをサブスクライブしたり,アンサブスクライブできる.ポイントは HTTP メソッドで POST と DELETE を使う点と,ヘッダーに Content-type: application/jsonContent-Length: 0 を乗せる点がある.この条件が満たされないと,エラーが返ってくる.

$ FIREBASE_SERVER_KEY=''
$ IID_TOKEN=''
$ TOPIC_NAME='test'
$ curl -XPOST --header "Authorization: key=${FIREBASE_SERVER_KEY}" \
  --header "Content-type: application/json" \
  --header "Content-Length: 0" \
  "https://iid.googleapis.com/iid/v1/${IID_TOKEN}/rel/topics/${TOPIC_NAME}"
$ FIREBASE_SERVER_KEY=''
$ IID_TOKEN=''
$ TOPIC_NAME='test'
$ curl -XDELETE --header "Authorization: key=${FIREBASE_SERVER_KEY}" \
  --header "Content-type: application/json" \
  --header "Content-Length: 0" \
  "https://iid.googleapis.com/iid/v1/${IID_TOKEN}/rel/topics/${TOPIC_NAME}"

その他

複数の登録トークンをバルクでサブスクライブするエンドポイントなど,他にもいろいろと提供されている.詳細はドキュメントを参照で.

  • https://iid.googleapis.com/iid/v1:batchAdd
  • https://iid.googleapis.com/iid/v1:batchRemove

まとめ

  • Firebase のプッシュ通知を検証した
  • FCM を使うと,HTTP 経由でプッシュ通知を送ることができる
  • トピックを使うことで,任意のグループにプッシュ通知を送ることができる
  • ただし,トピックの作成には最大1日かかる
  • Instance ID API を使うと,HTTP 経由で登録トークンを操作することができる

関連記事

inside.pixiv.net