Android应用后台长时间运行时(移动数据下)无法接收Firebase通知
React Native Android Firebase Messaging: Not Receiving Notifications on Mobile Data After 20 Minutes in Background
我之前在做React Native Android项目时刚好碰到过几乎一模一样的问题,结合Firebase Messaging在Android平台的特性,给你梳理几个核心排查方向和解决办法:
先盯紧厂商的电池优化
国内安卓厂商(小米、华为、OPPO这些)的电池优化逻辑会在应用后台闲置一段时间后,直接切断网络连接甚至杀死进程。这是最常见的原因:- 代码层面可以通过原生桥接调用,引导用户将应用排除在电池优化外:
// 示例Android原生代码,可封装成React Native模块调用 PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); if (!pm.isIgnoringBatteryOptimizations(getPackageName())) { Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); intent.setData(Uri.parse("package:" + getPackageName())); startActivity(intent); } - 也可以在应用内做引导,让用户手动去「设置-电池-电池优化」里把你的APP设为「不优化」。
- 代码层面可以通过原生桥接调用,引导用户将应用排除在电池优化外:
验证FCM的长连接状态
移动数据环境下,部分运营商或设备会在后台长时间无数据交互时主动切断TCP长连接,而FCM推送完全依赖这个长连接:- 在React Native里监听FCM的连接状态变化,确认20分钟后是否出现连接中断:
import messaging from '@react-native-firebase/messaging'; messaging().onTokenRefresh(token => { console.log('FCM连接重建,Token已刷新:', token); }); // 同时监听前台消息,确认连接正常时的接收情况 messaging().onMessage(message => { console.log('前台收到消息:', message); }); - 查看Android Logcat的
FirebaseMessaging相关日志,找有没有Connection closed due to inactivity这类连接断开的提示。
- 在React Native里监听FCM的连接状态变化,确认20分钟后是否出现连接中断:
检查后台服务配置
确保你的AndroidManifest.xml里FCM相关服务配置正确,避免系统回收进程后无法重启服务:<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service>对于Android 8.0+,必要时可以启动一个低优先级的前台服务(用透明通知占位),避免进程被系统强制杀死。
排查移动数据的后台限制
有些设备会单独限制应用的后台移动数据使用:- 引导用户去「设置-移动网络-应用数据管理」,找到你的APP,确保「后台数据」和「允许漫游数据」都处于开启状态。
- 部分设备的「智能省流量」功能也要把APP加入白名单,不然后台会被限流。
确认通知的发送类型
如果你发的是纯数据通知,需要应用进程存活才能接收;但如果是带notification字段的显示通知,会由系统的FCM服务直接处理,哪怕应用进程被杀死也能收到:
正确的payload示例:{ "to": "DEVICE_TOKEN", "notification": { "title": "测试通知", "body": "这是一条后台可接收的测试通知" }, "data": { "customKey": "customValue" } }
内容的提问来源于stack exchange,提问作者Shongsu
相关产品推荐
相关产品推荐

