Android CodelabのUsing Android Notificationsをやってみたの続きとなるAndroid Codelab。
Firebase Cloud Message(FCM)を使って通知を表示する。
対象のcodelab
Advanced Android in Kotlin 01.2: Android Firebase Cloud Messaging
ここで学べること
- Firebase Cloud Messagingを介してユーザーにメッセージをプッシュする方法
- Firebase Cloud Messagingの一部であるデータメッセージを使用して、バックエンドからアプリにデータを送信する方法
tokenを作成してFirebaseのコンソールからメッセージを送信
特定のトピックをsubscribeしメッセージ送信
特定のトピックをsubscribeすることで、その特定のトピックにオプトインしている複数のデバイスにメッセージを送信できる。 (ニュース、天気予報、スポーツの結果など、通知のカテゴリを示すために使用できる)
// EggTimerFragment.kt
private val TOPIC = "breakfast"
...
private fun subscribeTopic() {
FirebaseMessaging.getInstance().subscribeToTopic(TOPIC)
.addOnCompleteListener { task ->
var msg = getString(R.string.message_subscribed)
if (!task.isSuccessful) {
msg = getString(R.string.message_subscribe_failed)
}
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
}
}
トピックの設定 | スケジュール設定 |
---|---|
データを設定することもできる
LogcatでMessageを出力してみた例:
アプリがフォアグラウンドにあるときは、通知が表示されないため、 onMessageReceived
で通知を送信するコードを書くことで、通知を確実に受取るようにできる。
// MyFirebaseMessagingService.kt
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
// Not getting messages here? See why this may be: https://goo.gl/39bRNJ
Log.d(TAG, "From: ${remoteMessage?.from}")
// Check if message contains a data payload.
remoteMessage?.data?.let {
Log.d(TAG, "Message data payload: " + remoteMessage.data)
}
// Check if message contains a notification payload.
remoteMessage?.notification?.let {
Log.d(TAG, "Message Notification Body: ${it.body}")
sendNotification(it.body as String)
}
}
その他メモ
AndroidStudio経由デバッグモードでアプリを起動して、アプリをタスクキルした場合にFCMのメッセージを受信できなかった。 🤔
その後、ランチャーからアプリを起動してタスクキルした場合はFCMのメッセージを受信できた。
まとめ
- FirebaseMessagingServiceを継承したclassの
<service>
をAndroidManifest.xmlに追加 - 上記serviceで
onNewToken
で作成されたtokenを自webApiとかに送信してuserに紐付け登録する(今回はlogcatでコピペして手動だが) FirebaseMessaging.getInstance().subscribeToTopic(TOPIC).addOnCompleteListener
で特定のトピックをsubscribeする- FirebaseConsoleから上記のトピックへmessageの送信(これはFirebaseのAPIがあるので自WebApiとかから叩くことになるだろう)
onMessageReceived
で受信時の処理をかける(key/valueのデータの受け取りも可能)- アプリがフォアグラウンドのときは通知が表示されないので、確実に表示したいときは、
NotificationManager
をつかって自らsendNotificationすると良い