andnroid

Firebase Cloud Messaging (FCM) 推

2021-06-07  本文已影响0人  Edgar_Ng

近期一直在做Google的FCM推送工作,遇到不少坑,也遇到各种神奇事情.项目最近出街了,终于有空总结一下,算是造福国内开发者吧,FCM在国内的讨论相对比较少.
本文旨在描述常见问题,并非开发guide

汇总

  1. Q: APP为什么有时候能够收到消息,有时候收不到消息?
    A: FCM 分为两种接收消息的方式,前台接收后台接收.

    FCM 传送主题消息的方式与传送其他下行消息的方式相同。[1]
    如需接收消息,请使用继承 FirebaseMessagingService 的服务。 您的服务应该重写 onMessageReceivedonDeletedMessages 回调方法。该服务应在收到消息后 20 秒内对其进行处理(Android Marshmallow 上为 10 秒)。这个时长可能会更短,具体取决于调用 onMessageReceived 之前发生的操作系统延迟。这个时间段过后,各种操作系统行为(如 Android O 的后台执行限制)可能会影响您完成工作的能力。如需了解详情,请参阅我们的消息优先级概述。
    大多数类型的消息都会提供 onMessageReceived,但以下情况例外:

    • 当应用在后台时送达的通知消息。在这种情况下,通知将传送至设备的系统任务栏。默认情况下,用户点按通知即可打开应用启动器。

    • 在后台所接收的同时具备通知和数据载荷的消息。 在这种情况下,通知将传送至设备的系统任务栏,数据载荷则传送至启动器 Activity 的 intent 的 extras 属性中。

      前台/后台接收推送区别
  2. Q: 为什么我按照答案1做完之后还是不行?
    A: 请检查推送过来的数据格式是否正确,正确的格式应该是以下这样的[2]
    包含 notificationdata ,需要显示的 titlebody 应该包含在 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"
           }
         }
       }
    
  3. Q: 为什么Debug的时候发现能够收到消息,但是没有去到onMessageReceived?
    A: 后台收到消息的话,不会去onMessageReceived,而是走后台的方式.更多参考问题1

  4. Q: 为什么开了VPN还是拿不到 firebase token?
    A: 不是所有VPN都可以成功拿到firebase token. 目前来说,Lantern是已知拿到firebase token成功率比较高的VPN工具.
    具体验证方法,打开VPN后,能够打开Google Play Store,并成功浏览的VPN,一般无问题.

  5. 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
      如果stoppedtrue,则收不到的,如果stoppedfalse则是可以收到的.

    • 如果是中国国内的手机,不是所有国内手机都有安装GMS,没有安装GMS套装的手机,kill APP后的确不会接收FCM的消息推送.

    • FCM的推送率其实也不是百分百的,不要给PO/BA打包票

    • 部分国行三星机器会因为功率原因,会block FCM server,留意留意!

  6. 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" />
  1. Q: 设置了图标是彩色的,推送过来后显示的图标是一片灰色的?
    A: 叫UI designer 提供灰色透明底的PNG图片,之后再去set color即可.
    NotificationCompat.Builder().setColor()

  2. Q: 为什么通过postman FCM server 推送消息给手机, 试着试着手机就收不到了?
    A: 不要经常发同一内容的消息到同一台手机,会被FCM block的.可以改一改推送内容,又或者卸载APP(firebase token会改变)再重装即可.

  3. Q: 为什么kill APP后,已经收到的消息会消失(即在系统通知栏中的消息会消失)?
    A: 这是部分厂商的行为,淘宝/微博国际版也是一样.已知厂商:小米/三星
    部分厂商应该是对NotificationManager做了一些处理导致的,APP可以做的就只能搞很复杂的跨进程推送.

  4. Q: 为什么本地build的开发APP无问题,实际生产环境就收不到推送?
    A: 请保证包名无问题,实际生产环境使用的推送key也是对应production包名用的key

参考文档

  1. 接收和处理主题消息
  2. 数据格式结构
  3. 修改应用清单
  4. Firebase(FCM) notifications not coming when android app removed from recent tray
  5. Firebase push notification issue in Android when app is closed/killed
  6. Can Firebase console push notification if apps is closed?
  7. Can Firebase console push notification if apps is closed? -- Firebase 官方回答
上一篇下一篇

猜你喜欢

热点阅读