Androidアプリに、Firebase Cloud Messaging(以下FCM)を導入しました。
FCMをFirebaseConsoleからテスト送信を繰り返しデバッグしている時に、受信するアプリの起動状態によって、onMessageReceivedメソッドが呼ばれたり呼ばれなかったりしたので調べてみました。
FCMとは?
Firebase Cloud Messaging(FCM)は、メッセージを無料で確実に配信するためのクロスプラットフォーム メッセージング ソリューションです。
Firebase Cloud Messaging
onMessageReceivedメソッドが呼ばれない!?
FCMのテスト送信を行った時、アプリを起動していない状態だと仕込んでいたログが出ていないことに気づきました。全ての通知はonMessageReceivedで作成されると思っていたのですが、どうやらそうではないようです。(産休に入る前、GCMは確かそのような仕様だったはず。。やはり技術の変遷は早いですね)
アプリが起動している時
onMessageReceivedが呼ばれます。通知の際のタイトルや文字、アイコンはここで設定しているため、FCM送信の画面で設定している「通知のタイトル」や「通知テキスト」とは異なる設定にすることも可能です。
アプリを起動していない時
onMessageReceivedは呼ばれず、通知はデバイスの通知領域(システムトレイ)で処理されます。通知の際のタイトルや文字、アイコンはFCM送信の画面で設定している「通知のタイトル」や「通知テキスト」がそのまま使用されます。
Intentはどうやって渡す?
この挙動の違いで困ったことがありました。onMessageReceivedで作成した通知で、通知から呼ばれるActivityにIntentを渡していたことです。onMessageReceivedを通らないとなれば、どうやって値を渡そうかと調べてみると、FCM送信の設定でIntentも渡すことができました!
FCM送信の画面の、「5.その他のオプション(省略化)」> 「カスタムデータ」の設定をすることで、Intentを渡すことができます。



アプリが起動した際、Intentで渡したデータは、onMessageReceivedで設定した場合も、FCM送信の画面で設定した場合も、下記のソースで受け取ることが可能です。
// インテントを取得
Intent intent = getIntent();
// 値を取得
String value = intent.getStringExtra("key"); // putExtra(key, value)で設定した値を取得
まとめ
今回はFCMを受信した時のアプリの状態によって、onMessageReceivedが呼ばれたり呼ばれなかったりしたことについて書きました。FCMドキュメントにはよくよく読むとちゃんと書いてあるのですが、昔の仕様に引き摺られたり、「バックグラウンド状態」というのをActivityのライフサイクルの話と混合していたりと、なかなかにブランクを感じたハマりポイントでした。