複数端末を所持している人を考慮してプッシュ通知を送る
Gmailとかハングアウトとかって、複数端末で通知を受けても、1つの端末で消せばちゃんと全部の端末で通知消えるんですよね。
これがやりたい。
あれ、どうやるの? という話です。
ざっくり
プッシュを受け取った端末が「受け取ったよ!」って空プッシュを送って send-to-sync する、みたいなことをやらないといけないようです。
以下のリファレンスを見ると、Device Group Messagingというのをつかうだけで、GCMがいい感じにやってくれるようにも見えますが、実際に動かしてみると、プッシュ消去は同期されませんでした・・・・・・。
http://www.androiddocs.com/google/gcm/notifications.html
https://firebase.google.com/docs/cloud-messaging/android/device-group
Device Group Messaging
FCMには、メッセージ送信の to
パラメータにグループを指定することで、そのグループに属する端末たちの通知が同期される仕組みがあります。
グループがあれば、個々のデバイストークンを指定せずにメッセージが送れるので、ユーザ単位でプッシュを送りたいケースでは、1デバイスであっても使う価値はありそうです。
グループ?
https://android.googleapis.com/gcm/notification というエンドポイントにPOSTリクエストを出すことで、グループのメンバー管理ができるようです。
初めてグループを作るとき
{
"operation": "create",
"notification_key_name": "HogeAppUser0003",
"registration_ids": ["xxxxx", "yyyyy"]
}
みたいなのをPOSTすると、グループのID文字列(notification_key)が返ってくるので、
それをどこかに覚えておいて送信時に使います。
registration_id は、Androidアプリ側で FirebaseInstanceId.getInstance().getToken();
で取得できるやつを指定。(これ、リファレンスには曖昧な書き方されてて、ちょっとハマるとこw)
グループにメンバーを追加・削除するとき
{
"operation": "add",
"notification_key": "作成時にもらったグループのID文字列",
"registration_ids": ["zzzzz"]
}
とか
{
"operation": "remove",
"notification_key": "作成時にもらったグループのID文字列",
"registration_ids": ["xxxxx"]
}
とかをPOSTすると、グループのID文字列(notification_key)が返ってきて成功! となります。
非常にくせのある仕様・・・
https://android.googleapis.com/gcm/notification のAPIは、
グループが0人か1人以上かによって挙動が変わります。これがすごくめんどくさい。
おそらく
- 0人の時→createのみ可能。新規notification_keyが発行される。
- 1人の時→add/removeのみ可能。notification_keyが引き継がれる
のような仕様なんだと思うんですが、
-
create
したあとcreate
→400エラー -
create
したあと同じ人をadd
→200 OK (notification_keyが返る) -
add
したあと同じ人をadd
→200 OK (notification_keyが返る)
あたりはわかるんですが、
-
create
もしくはadd
した人をremove
→200 OK ・・・ notification_keyが返るが、グループの残りが0人だったら、もうこのnotification_keyは使えない -
remove
した人をremove
→ グループメンバーがのこり0人であれば 400エラー 、1人以上いたら 200 OK -
remove
した人をadd
→ グループメンバーがのこり0人であれば 400エラー 、1人以上いたら 200 OK -
remove
した人をcreate
→グループメンバーが0人であれば 200 OK、 1人以上いたら 400エラー
あたりは、かなりくせっぽいなー (≒ こんな管理をやりたくないなー) と・・・w
ちなみに、Androidアプリから登録する際には、notification_key の指定無しで add/removeができるので、このようなめんどくさい考慮はいりません。(が、別のめんどくさい考慮が必要です・・・後述)
誰がメンバー管理をするべきか?
基本的に、「サーバーサイドで端末グループ管理なんて自前でやりたくないよー」っていう場合のことを書きます。
パターン1 グループ登録までAndroid側でやる
Android側で
- ユーザIDから、一意で推測されにくい文字列を生成する ・・・これをグループ名としてつかう
- アプリにログイン完了後、FCMトークンを取得し、グループを作成 or メンバー追加する
- グループIDをサーバに送る
みたいなことをやる流れになります。
サーバーサイドでは
User has_one fcm_group_key
みたいな関連を持っておくだけでプッシュが送れるので、シンプルな構成になります。
ただ、AndroidのAPIは、 id_token
が必要で、こいつは Googleログインを組み込んであげないと取得できない シロモノでして・・・
まぁ頑張って実装しましょう・・・。
とはいかないこともあるので・・・
パターン2 サーバー側でグループ登録処理だけはやる
Android側
- アプリにログイン完了後、FCMトークンを取得後、それをサーバーに送る
サーバー側
- もらったFCMトークンをもとに、グループを作成 or メンバー追加する
- グループIDを登録する
という流れになります。
この場合は
User
has_many fcm_tokens
has_one fcm_group_key
のように2つの関連をもつことになるでしょう。
誰がどのグループに属しているかは知らなくてもよいですが、先に述べたような「くせのある仕様」を攻略する必要があります。
とはいえ、端末個別にもプッシュはおくりたいし、端末グループ単位(ユーザごと)にもプッシュはおくりたい、 という場合は必然的にこちらのパターンを採用することになるでしょう・・・。
で、どっちがいいの? といわれると、
- サーバー側でFCMトークンを持つということ自体が何かと不便
- そもそも端末単位で送りたいプッシュなんて、そんなにないでしょ?
という独断と偏見で、私はパターン1をおすすめします。 が、システムによって要件はまちまちなので、そこは適宜考えて下さい。
まとめ
まず、プッシュ通知をおくる、となったときには
- 重要じゃない(≒ アプリの機能と関係のない)通知を送ろうとしてないか?
- プッシュ通知頻度は適正か?
だけでなく、
- 複数端末にプッシュした際に、プッシュの消去が同期されるべきか、否か?
という観点を持ちましょう。
プッシュの消去を同期したかったら Device Group Messaging を使いましょう。
Author And Source
この問題について(複数端末を所持している人を考慮してプッシュ通知を送る), 我々は、より多くの情報をここで見つけました https://qiita.com/YusukeIwaki/items/baa03f9a982c44254dbb著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .