应用关闭时无法接收无通知负载的FCM消息求助
FCM纯Data消息在应用终止状态下无法接收的问题排查与解决
问题场景
应用处于**终止(完全关闭)**状态时,无法接收不含通知负载的FCM Data消息,但应用在前台或后台(最小化)状态下接收正常。
核心原因分析
FCM的Data消息在应用终止状态下的投递依赖系统唤醒FirebaseMessagingService,但国内安卓厂商的后台管控(电池优化、自启动限制)会阻止系统唤醒服务;同时消息格式、服务注册配置、启动逻辑的问题也可能导致消息无法触发onMessageReceived。
针对性解决方案
1. 突破厂商后台限制
国内小米、华为、OPPO、Vivo等厂商的后台管控会拦截非白名单应用的唤醒请求,需手动配置:
- 开启自启动权限:设置→应用管理→你的应用→权限管理→开启「自启动」
- 关闭电池优化:设置→电池→电池优化→找到你的应用,设置为「不允许优化」
2. 确认FirebaseMessagingService注册正确性
检查AndroidManifest.xml中服务注册和权限声明:
<!-- 必要权限 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- Firebase消息服务注册 --> <service android:name=".你的FirebaseMessagingService实现类" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
3. 优化onMessageReceived执行逻辑
- 应用终止时启动Activity需补充flag,避免栈异常:
// 修改ringing分支的Activity启动代码 val i = Intent(applicationContext, IncomingCallActivity::class.java) i.putExtra("uid", senderUid) i.putExtra("email", senderEmail) i.putExtra("name", senderName) i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) startActivity(i) - 对于
accepted/rejected/hangup这类无活跃组件监听的广播,建议将状态存储到SharedPreferences或Room,待应用启动后再读取处理。
4. 严格控制消息发送格式
确保发送的是纯Data消息,不能混合notification字段(否则应用终止时系统直接展示通知,不会触发onMessageReceived),正确格式示例:
{ "to": "目标设备FCM_TOKEN", "data": { "status": "ringing", "uid": "接收方UID", "senderName": "发送方名称", "senderEmail": "发送方邮箱", "senderUid": "发送方UID" } }
5. 启用高优先级投递
对于通话这类实时场景,发送高优先级消息确保系统立即投递:
{ "to": "目标设备FCM_TOKEN", "priority": "high", "data": { "status": "ringing", // 其他字段 } }
高优先级消息会唤醒休眠设备,强制触发onMessageReceived。
调试建议
- 使用Firebase Console发送「自定义数据」类型测试消息,验证终止状态下的接收情况
- 查看Logcat中
FirebaseMessaging相关日志,确认消息是否被系统接收 - 在不同品牌设备上测试,适配不同厂商的后台规则
内容的提问来源于stack exchange,提问作者Saad Ahmed
相关产品推荐
相关产品推荐

