近期一直在做Google的FCM推送工作,遇到不少坑,也遇到各种神奇事情.项目最近出街了,终于有空总结一下,算是造福国内开发者吧,FCM在国内的讨论相对比较少.
本文旨在描述常见问题,并非开发guide
汇总
-
Q: APP为什么有时候能够收到消息,有时候收不到消息?
A: FCM 分为两种接收消息的方式,前台接收和后台接收.FCM 传送主题消息的方式与传送其他下行消息的方式相同。[1]
如需接收消息,请使用继承FirebaseMessagingService
的服务。 您的服务应该重写onMessageReceived
和onDeletedMessages
回调方法。该服务应在收到消息后 20 秒内对其进行处理(Android Marshmallow 上为 10 秒)。这个时长可能会更短,具体取决于调用onMessageReceived
之前发生的操作系统延迟。这个时间段过后,各种操作系统行为(如 Android O 的后台执行限制)可能会影响您完成工作的能力。如需了解详情,请参阅我们的消息优先级概述。
大多数类型的消息都会提供onMessageReceived
,但以下情况例外:当应用在后台时送达的通知消息。在这种情况下,通知将传送至设备的系统任务栏。默认情况下,用户点按通知即可打开应用启动器。
-
在后台所接收的同时具备通知和数据载荷的消息。 在这种情况下,通知将传送至设备的系统任务栏,数据载荷则传送至启动器 Activity 的 intent 的 extras 属性中。
-
Q: 为什么我按照答案1做完之后还是不行?
A: 请检查推送过来的数据格式是否正确,正确的格式应该是以下这样的[2]
包含notification
和data
,需要显示的title
和body
应该包含在notification
里面,不要放到其他地方. 如果只在data
那里有内容,notification
那里没有内容的话, 一般是不会收到消息的. [4]请确保未在自定义键值对中使用任何保留字词。保留字词包括 “from”、“notification”、“message_type” 或以 “google” 或 “gcm” 开头的任何字词。
{ "message":{ "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "notification":{ "title":"Portugal vs. Denmark", "body":"great match!" }, "data" : { "Nick" : "Mario", "Room" : "PortugalVSDenmark" } } }
Q: 为什么Debug的时候发现能够收到消息,但是没有去到
onMessageReceived
?
A: 后台收到消息的话,不会去onMessageReceived
,而是走后台的方式.更多参考问题1Q: 为什么开了VPN还是拿不到 firebase token?
A: 不是所有VPN都可以成功拿到firebase token. 目前来说,Lantern是已知拿到firebase token成功率比较高的VPN工具.
具体验证方法,打开VPN后,能够打开Google Play Store,并成功浏览的VPN,一般无问题.-
Q: 为什么某些手机关了APP后总是收不到消息?
A:请看答案2
-
有些第三方厂商会设置电源模式,会限制APP的通讯,可以打开电源管理,之后选择[无限制]后再去尝试,还有[自启动]管理,需要都打开(已知厂商: 华为/OPPO/小米),小米打开[自启动]即可收到消息. [7]
具体验证方法如下:输入
adb shell dumpsys package "包名" | grep stopped
之后console输出User 0: ceDataInode=249503 installed=true hidden=false suspended=false distractionFlags=0 stopped=true notLaunched=false enabled=0 instant=false virtual=false
如果stopped
为true
,则收不到的,如果stopped
是false
则是可以收到的. 如果是中国国内的手机,不是所有国内手机都有安装GMS,没有安装GMS套装的手机,kill APP后的确不会接收FCM的消息推送.
FCM的推送率其实也不是百分百的,不要给PO/BA打包票
部分国行三星机器会因为功率原因,会block FCM server,留意留意!
Q: 为什么接收消息的图标不对,显示为一个灰色的图标,或者显示为APP的图标icon?
A: 当后台接收消息时,会使用默认的图标,没有的话会使用APP的icon.
将以下代码行添加到 application 标记内,以设置自定义默认图标和颜色:
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
Q: 设置了图标是彩色的,推送过来后显示的图标是一片灰色的?
A: 叫UI designer 提供灰色透明底的PNG图片,之后再去set color即可.
NotificationCompat.Builder().setColor()
Q: 为什么通过postman FCM server 推送消息给手机, 试着试着手机就收不到了?
A: 不要经常发同一内容的消息到同一台手机,会被FCM block的.可以改一改推送内容,又或者卸载APP(firebase token会改变)再重装即可.Q: 为什么kill APP后,已经收到的消息会消失(即在系统通知栏中的消息会消失)?
A: 这是部分厂商的行为,淘宝/微博国际版也是一样.已知厂商:小米/三星
部分厂商应该是对NotificationManager
做了一些处理导致的,APP可以做的就只能搞很复杂的跨进程推送.Q: 为什么本地build的开发APP无问题,实际生产环境就收不到推送?
A: 请保证包名无问题,实际生产环境使用的推送key也是对应production包名用的key
参考文档
- 接收和处理主题消息
- 数据格式结构
- 修改应用清单
- Firebase(FCM) notifications not coming when android app removed from recent tray
- Firebase push notification issue in Android when app is closed/killed
- Can Firebase console push notification if apps is closed?
- Can Firebase console push notification if apps is closed? -- Firebase 官方回答