前回、下記のエントリでProgressive Web Appにおけるそこそこ生のWeb-Push-Protocolについておおまかな仕組みを触れました
ので、今回はFirebase Cloud Messagingを使って、もっと手軽にWebブラウザにPush通知を送るのをやってみた備忘録です。
公式ドキュメント
- Set Up a JavaScript Firebase Cloud Messaging Client App | Firebase
- Receive Messages in a JavaScript Client | Firebase
- Send Messages to Multiple Devices | Firebase
必要なもの
- GCM Sender ID
- ブラウザ(デバイス)側で、Subscriptionを発行するときに、このアプリケーションの所属を明らかにするために必要
- WebPushProtocolにおけるApplicationServerPublicKeyをFirebaseがラップしている要素だと思えばよい
- FCM Server Key
- 自前サーバ側で、FCMを叩くときに、アプリケーションの所属と妥当性を明らかにするために必要
- WebPushProtocolにおけるApplicationServerPrivateKeyをFirebaseがラップしている要素だと思えばよい
どっちもFirebase consoleで手に入る。
- Firebase consoleに行き、[プロジェクトを追加]する(図)
- [ウェブアプリにFirebaseを追加]を選択(3つ並んだ◯の右の赤いやつ)
messagingSenderId
というのがあるので、これがGCM_SENDER_ID
です- つづいて、左上、[Overview]の隣の設定アイコンから[プロジェクトの設定]を選択
- 上部のタブのうち[クラウドメッセージング]を選択
6.
サーバーキー
というのがあるので、これがFCM_SERVER_KEY
です
やること
- ブラウザのタブで動くmain.js
- firebaseアプリケーションの初期化
- messagingモジュールの初期化
- 自動で
/firebase-messaging-sw.js
をServiceWorkerとしてregisterしようとする
- 自動で
- Notificationの許可と、DeviceToken取得できたら自前サーバにそれを送る
- バックグラウンドで動き続けるfirebase-messaging-sw.js
- ブラウザタブがactiveでないときにPush通知が来たときのハンドラを設定できる
- ちょっと癖がある
- ブラウザタブがactiveでないときにPush通知が来たときのハンドラを設定できる
- 自前のサーバserver.js
- ブラウザから送りつけられてきた各ユーザのDeviceTokenの保存
- 何らかのきっかけでFCMのエンドポイントを叩く
- payloadのtoというフィールドでPush通知を投げたい相手のDeviceTokenを指定する
- もちろんjsである必要はない全く無い
うるせえ動くコード見せろ
ウッス
% git clone git@github.com:otiai10/firebase-messaging-sample.git % cd firebase-messaging-sample % GCM_SENDER_ID={上記の} \ FCM_SERVER_KEY={上記の(けっこう長い)} \ node server.js
こんな感じでうごく
注意点・ハマったポイント
manifest.jsonのgcm_sender_idは"103953800507"
- 問題: ブラウザのコンソールで「Messaging: Please change your web app manifest’s ‘gcm_sender_id’ value to ‘103953800507’ to use Firebase messaging. (messaging/incorrect-gcm-sender-id).」と叱られる
- 原因: これは、実際にPush通知を送る主体はFirebaseのサーバなので、FirebaseのアプリケーションIDを登録する必要があるため
- 解決: ハードコードで103953800507を指定する manifest.json
setBackgroundMessageHandlerで設定したハンドラが呼ばれてない
- 問題:
firebase-messaging-sw.js
において、setBackgroundMessageHandler
を使ってハンドラを登録しているのにもかかわらず、ぜんぜん呼ばれてる気配が無い - 原因:
- その1: ブラウザのタブがactiveな時は必ず、ブラウザタブのmain.jsにおける
messaging.onMessage
が呼ばれるので、ServiceWorkerには入らない - その2: これが上記で「癖がある」って言ったやつなんですけど、自前サーバ側でFirebase叩くときに、そのペイロード中に
notification
というフィールドのデータが入っていると、そのnotification
で指定したtitle
,body
,icon
でNotificationが生成され、ServiceWorkerには入らない。ふしぎだね。
- その1: ブラウザのタブがactiveな時は必ず、ブラウザタブのmain.jsにおける
- 解決: まずブラウザのタブを閉じる。そんで、サーバからのFCMへのリクエストのトップに
notification
というフィールドを含めない- つまりサンプルコードのこのFCMの叩き方だと、一生
setBackgroundMessageHandler
のハンドラには入らないということです
- つまりサンプルコードのこのFCMの叩き方だと、一生
雑感
- 暗号化その他もろもろFirebaseがやってくれるので、やっぱり素でWeb-Push-Protocolに乗るより断然お手軽だった
- 癖があるところとか、ほげほげKEYが多すぎて混乱するところとかはあるけども
- 酒が弱くなってる。よいことだ。
DRYな備忘録として
- 作者: Charles Severance
- 出版社/メーカー: Oreilly & Associates Inc
- 発売日: 2009/05
- メディア: ペーパーバック
- 購入: 2人 クリック: 51回
- この商品を含むブログ (3件) を見る
Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門
- 作者: 前橋和弥
- 出版社/メーカー: 技術評論社
- 発売日: 2016/06/07
- メディア: Kindle版
- この商品を含むブログを見る
- 作者: 松田承一
- 発売日: 2016/08/25
- メディア: Kindle版
- この商品を含むブログを見る