railsでFCMを使用しpush通知を行う
railsで作成したサーバーアプリから
FCMを使ってアプリにpush通知を送信する方法をまとめました。
FCMとは
Firebase Cloud Messagingのことで
Googleが提供しているモバイル プラットフォームであるFirebaseの1機能になります
iOS/Androidの端末にデータ転送が行えるサービスになり
素晴らしいのが、基本無料で使えるということです。
アーキテクトの説明はこちらで
https://firebase.google.com/docs/cloud-messaging/fcm-architecture?hl=ja
前提
- Firebaseのアカウント、プロジェクトは作成済み
- API系のサーバーキーも作成済み
- アプリ側で登録トークン処理が実装済み
アプリ側の実装方法はこちらを参考に
・iOS
https://firebase.google.com/docs/cloud-messaging/ios/client
・Android
https://firebase.google.com/docs/cloud-messaging/android/client
開発環境
- ruby 2.6.5
- Rails 6.0.2
- fcm(gem) 0.0.7
rubyのSDKについて
まず最初にFCMのSDKには、この記事を書いている2022/4/16時点ではrubyが存在していないです。
https://firebase.google.com/docs/admin/setup/
そのためgemを使用し開発を進めていこうと思います。
gemの名前はそのままで「fcm」となります
https://rubygems.org/gems/fcm/
Firebaseのプッシュ通知について
Firebaseのプッシュ通知には大きく分けて以下の2種類があります。
■Firebase Notifications
Firebaseの管理画面からプッシュ通知を送る方式で、サーバー側の開発が無いこともあり
導入しやすいメリットがありますが、APIが存在していないため
システムとの連携部分においては厳しい部分があります
■FCM (Firebase Cloud Messaging)
FCMは、HTTP経由でプッシュ通知を送る方式になります。
FCMの中にも2種類のメッセージタイプがありますが
Notification Message と Data Messageを併用して使うこともできます。
https://firebase.google.com/support/faq/#messaging-difference
・Notification Message
送信データ内にnotificationが含まれる場合は、通知メッセージとして扱われる
プッシュ通知はSDK側で自動表示される。
1 2 3 4 5 6 7 8 9 |
{ message: { token: "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", notification: { title: "Portugal vs. Denmark", body: "great match!" } } } |
・Data Message
送信データ内にnotificationが含まれない場合は、データメッセージとして扱わる。
アプリ側でプッシュ通知を表示させるために実装する必要がある。
1 2 3 4 5 6 7 8 9 10 |
{ message: { token:"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", data: { Nick: "Mario", body: "great match!", Room: "PortugalVSDenmark" } } } |
プッシュ通知の送信対象
送信対象となるタイプは大きく2種類あります。
-
token
端末ごとに発行されるFCMトークンを指定して通知する
送信対象者が状況・条件によって変わる場合や特定ユーザーにのみ配信したい場合に主に使用される。会員登録や物を購入した時に送るなどが該当するかと思います。 -
topic
設定したグループに登録されている端末に通知する
条件に沿ったグループを作成し、マッチしたユーザーを登録しておく。
送信が必要になったタイミングで、送信対象をそのグループにすると条件にあったユーザに通知がいく仕組む
実装
token、topicそれぞれの送信方法を、実際に作成していきます。
registration_idはFCMトークンの意味合いで説明します。
tokenでの実装
FCM_SERVER_KEYはFirebaseのFCMのサーバーキーになります。
registration_idsは送信端末が1件でも配列にする必要があります。
1リクエストでregistration_idsを指定できる数は1000になりますので
1000以上送る場合は、リクエストを分割して送る必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
fcm = FCM.new("#{FCM_SERVER_KEY}") registration_ids = ["eyRQP......:ddddddd....."] options = { priority: 'high', notification: { title: "送信テスト", body: "本文が入ります。", badge: 1, sound: "default" } } response = fcm.send(registration_ids, options) if response[:status_code] != 200 Rails.logger.error response[:response] end |
topicでの実装
FCM_SERVER_KEYはFirebaseのFCMのサーバーキーになります。
■topicにregistration_idを登録
指定したregistration_idの端末が、既にアプリを削除していると
レスポンスのステータスコードは404になります。
https://firebase.google.com/docs/reference/fcm/rest/v1/ErrorCode
1つのregistration_idが登録できるtopicの数は2000になります
1つのtopicに対して登録できるregistration_idは無制限です。
https://firebase.google.com/docs/cloud-messaging/ios/topic-messaging?hl=ja
1 2 3 4 5 6 |
topic_name = "test_push" fcm = FCM.new("#{FCM_SERVER_KEY}") response = fcm.topic_subscription(topic_name, registration_id) if response[:status_code] == 200 # 追加成功 end |
■メッセージを送信
基本的にはtopic名と送信したいデータを設定するだけになります。
画像も送信したい場合ですが、
mutable-content を設定することによって、
受信側クライアントのサービス拡張はペイロードで配信された画像を処理できます。
https://firebase.google.com/docs/cloud-messaging/ios/send-image?hl=ja#rest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
topic_name = "test_push" fcm = FCM.new("#{FCM_SERVER_KEY}") options = { topic: topic, notification: { title: "送信テスト", body: "本文が入ります。", image: "http://example.com/image.png" }, apns: { payload: { aps: { "mutable-content": 1 } } } } response = fcm.send_to_topic(topic_name, options) if response[:status_code] == 200 # 送信成功 end |
無料で使えるのもそうですが、簡単にデータ作成できるのが凄いですね。
token方式、topic方式それぞれの利点があるので
使い分けができる設計にできれば強みになりますね!
ありがとうございました。