Android FCM onMessageReceived的运行时机总结

mac2025-06-08  49

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。文档对这个情况的论述如下截图所示:

 

 

最新回复(0)