FCM消息的官方文档:
https://firebase.google.com/docs/cloud-messaging/concept-options
https://firebase.google.cn/docs/cloud-messaging/concept-options(中文镜像网址)
简单来说,FCM 消息有两种类型,一种是Notification消息,消息的Json格式中有notification包裹(仅有notification!!):
"notification":{ "title":"Portugal vs. Denmark", "body":"great match!" }另一种是Data消息,消息的Json格式中有notification包裹:
"data":{ "Nick" : "Mario", "body" : "great match!", "Room" : "PortugalVSDenmark" }如果消息格式中notification字段和data字段并存,那么这个消息被划归为一个Notification消息。值得注意的是:如果Json中只有一个data{}包裹,但是里面有个字段名叫 “gcm.notification.XXX”,那么这个消息即使没有notification字段,也会被划归为一个Notification消息。
上面先写消息类型的原因,是因为FirebaseMessagingService子类中的onMessageReceived这个接收函数的执行时机,跟消息的类型息息相关。下文结论中的MyFirebaseMessagingService是FirebaseMessagingService的子类,很神奇的一点是,如果用了FCM会发现,即使APP没运行把APP给杀掉了,这时候如果收到了FCM通知,APP里的MyFirebaseMessagingService里面的onMessageReceived回调也会被调用执行!!!!这个Service在APP被杀掉以后,还是由系统级别去保活的(当然如果手机锁屏休眠进入低电耗模式Doze的话,这个回调就不会被执行了)。在下面用PushTry这个测试网址(https://pushtry.com/)对数据的类型做一个情况验证汇总( 注意: 诸如华为的很多国产手机系统都改了,APP杀死以后不会维持FCM服务的长链接,如果是国产手机集成,那么杀了APP以后很可能不会收到消息,onMessageReceived是不会执行的)。
情况验证:
(情况1: 数据消息:不带notification字段,不带gcm.notification.XXX字段,带"priority": "high")
{
"to":"fdw5LvWvTxY:APA91bFuZlEpR8FUL_Xm7iiFfUA5FANF5GGFUEciLrzTMsYVNRqafUk3v9ik9CVCW08blswDO-Q4JXRW7DqWTlwBqXYeKFHovJw9h6Y3zU-hhFcMPPbFeC7X7v8IKA0aqWDdHNcQqZy-",
"priority": "high",
"data": {
"darjeeling_silent": "{\"_rtp.mid\":\"1650342847\",\"_rtp.c.url\":\"https://news.livedoor.com/topics/detail/17235012/\",\"_rtp.c.imageUrl\":\"https://image.news.livedoor.com/newsimage/stf/4/4/446e6_103_47e22b6d4ce2b183709fc1cb8f1a35b9.jpg\",\"_rtp.ddt\":\"201910171600\"}",
"darjeeling_key": "darjeeling",
"id": "265736873",
"title": "fenrir.wang.testTry",
"message": "fenrir.wang.testTry",
"attr3": "http://bcp.myrerescue.net/anpi/sts?accskey=qPk7KzEo7R1b9W617360"
}
}
APP在前台的时候收到消息:执行MyFirebaseMessagingService:onMessageReceived,通知栏里可见通知
APP在后台的时候收到消息:执行MyFirebaseMessagingService:onMessageReceived,通知栏里可见通知
APP在杀死的时候收到消息:执行MyFirebaseMessagingService:onMessageReceived,通知栏里可见通知
++++++++++++++++++++++++++++++++++++
(情况2: 数据消息:不带notification字段,不带gcm.notification.XXX字段,不带"priority": "high")
{
"to":"fdw5LvWvTxY:APA91bFuZlEpR8FUL_Xm7iiFfUA5FANF5GGFUEciLrzTMsYVNRqafUk3v9ik9CVCW08blswDO-Q4JXRW7DqWTlwBqXYeKFHovJw9h6Y3zU-hhFcMPPbFeC7X7v8IKA0aqWDdHNcQqZy-",
"data": {
"darjeeling_silent": "{\"_rtp.mid\":\"1650342847\",\"_rtp.c.url\":\"https://news.livedoor.com/topics/detail/17235012/\",\"_rtp.c.imageUrl\":\"https://image.news.livedoor.com/newsimage/stf/4/4/446e6_103_47e22b6d4ce2b183709fc1cb8f1a35b9.jpg\",\"_rtp.ddt\":\"201910171600\"}",
"darjeeling_key": "darjeeling",
"id": "265736873",
"title": "fenrir.wang.testTry",
"message": "fenrir.wang.testTry",
"attr3": "http://bcp.myrerescue.net/anpi/sts?accskey=qPk7KzEo7R1b9W617360"
}
}
APP在前台的时候收到消息:执行MyFirebaseMessagingService:onMessageReceived,通知栏里可见通知
APP在后台的时候收到消息:执行MyFirebaseMessagingService:onMessageReceived,通知栏里可见通知
APP在杀死的时候收到消息:执行MyFirebaseMessagingService:onMessageReceived,通知栏里可见通知
++++++++++++++++++++++++++++++++++++
(情况3: 通知消息:带notification字段,不带gcm.notification.XXX字段,带"priority": "high”)
{
"to":"fdw5LvWvTxY:APA91bFuZlEpR8FUL_Xm7iiFfUA5FANF5GGFUEciLrzTMsYVNRqafUk3v9ik9CVCW08blswDO-Q4JXRW7DqWTlwBqXYeKFHovJw9h6Y3zU-hhFcMPPbFeC7X7v8IKA0aqWDdHNcQqZy-",
"priority": "high",
"data": {
"darjeeling_silent": "{\"_rtp.mid\":\"1650342847\",\"_rtp.c.url\":\"https://news.livedoor.com/topics/detail/17235012/\",\"_rtp.c.imageUrl\":\"https://image.news.livedoor.com/newsimage/stf/4/4/446e6_103_47e22b6d4ce2b183709fc1cb8f1a35b9.jpg\",\"_rtp.ddt\":\"201910171600\"}",
"darjeeling_key": "darjeeling",
"id": "265736873",
"title": "fenrir.wang.testTry",
"message": "fenrir.wang.testTry",
"attr3": "http://bcp.myrerescue.net/anpi/sts?accskey=qPk7KzEo7R1b9W617360"
},
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
}
APP在前台的时候收到消息:执行MyFirebaseMessagingService:onMessageReceived,通知栏里可见通知
APP在后台的时候收到消息:不执行MyFirebaseMessagingService:onMessageReceived,通知栏里可见通知
APP在杀死的时候收到消息:不执行MyFirebaseMessagingService:onMessageReceived,通知栏里可见通知
++++++++++++++++++++++++++++++++++++++++++++++
如果发送FCM消息的时候手机关机了,那么在开机以后当建立FCM连接以后会把关机收到的这段消息发送到手机设备,然后执行onMessageReceived。文档对这个情况的论述如下截图所示: