React Native Android应用无法接收Firebase推送通知求助
嘿,我看你已经搞定了FCM Token的获取,但卡在了接收手动推送这一步——这种情况我碰到过好几次,结合你的代码和Android配置,给你梳理几个关键的修复点:
1. 移除Manifest里冲突的FCM服务
你的Android清单文件里同时加了io.invertase.firebase.messaging和com.evollu.react.fcm两套服务,这会让系统搞不清该用哪套来处理推送事件,直接导致通知收不到。
怎么改:
删掉invertase那两个服务声明,只保留com.evollu.react.fcm相关的:
<!-- 删掉下面这两段 --> <service android:name="io.invertase.firebase.messaging.MessagingService" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <service android:name="io.invertase.firebase.messaging.InstanceIdService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/> </intent-filter> </service>
2. 注意Firebase控制台的推送类型
你手动发通知的时候,一定要选**「通知」标签页**,填好标题和内容——如果只发纯数据消息,Android系统不会自动弹出通知,得你在代码里手动触发本地通知才行。
简单说:别只在「数据」里填键值对,一定要走「通知」通道发。
3. 整理代码里的通知监听逻辑
你的代码里重复注册了两次FCMEvent.Notification监听(全局一次,componentDidMount里又一次),虽然不会直接导致收不到通知,但容易搞混逻辑。建议合并成一个监听,顺便加上前台通知的手动展示逻辑(Android前台默认不弹通知):
优化后的代码参考:
import { Platform } from 'react-native'; import FCM, { FCMEvent, RemoteNotificationResult, WillPresentNotificationResult, NotificationType } from 'react-native-fcm'; class App extends Component { componentDidMount() { // 请求通知权限 FCM.requestPermissions() .then(() => console.log('通知权限已授权')) .catch(() => console.log('通知权限被拒绝')); // 获取并存储FCM Token FCM.getFCMToken().then(token => { console.log('当前FCM Token:', token); // 这里把Token上传到你的服务器 }); // 监听所有通知事件 this.notificationListener = FCM.on(FCMEvent.Notification, async (notif) => { console.log('收到通知:', notif); // 本地通知无需额外处理 if (notif.local_notification) return; // 用户点击通知打开应用的逻辑 if (notif.opened_from_tray) { console.log('用户通过通知栏打开了应用'); // 这里可以加页面跳转逻辑,比如根据notif.data的参数跳转到对应页面 } // Android前台收到通知时,手动弹出本地通知 if (Platform.OS === 'android' && !notif.opened_from_tray) { FCM.presentLocalNotification({ title: notif.notification.title, body: notif.notification.body, priority: 'high', show_in_foreground: true, local: true }); } // iOS的通知收尾逻辑,按官方要求处理 if (Platform.OS === 'ios') { switch(notif._notificationType){ case NotificationType.Remote: notif.finish(RemoteNotificationResult.NewData); break; case NotificationType.NotificationResponse: notif.finish(); break; case NotificationType.WillPresent: notif.finish(WillPresentNotificationResult.All); break; } } }); // 监听Token刷新事件 this.refreshTokenListener = FCM.on(FCMEvent.RefreshToken, (token) => { console.log('FCM Token已刷新:', token); // 更新服务器上的Token }); // 获取启动应用的初始通知(比如用户点击通知启动应用) FCM.getInitialNotification().then(notif => { console.log('启动应用的初始通知:', notif); if (notif) { // 处理应用被通知启动的逻辑 } }); } componentWillUnmount() { // 组件卸载时移除所有监听,避免内存泄漏 this.notificationListener.remove(); this.refreshTokenListener.remove(); } // ... 你的其他组件代码 }
4. 检查Firebase配置文件
确保google-services.json已经放在android/app目录下,而且文件里的package_name和你Manifest里的package="fi.rogerstudio.possis"完全一致——这个细节很容易忽略,但错了就会导致推送失败。
5. 分场景测试通知
- 前台状态:Android默认不会弹通知,所以需要上面代码里的
presentLocalNotification手动触发; - 后台/杀死状态:如果还是收不到,那大概率是Manifest的服务配置错了,或者Firebase项目里的包名没对应上。
改完这些之后,重新打包安装应用,再去Firebase控制台发个通知试试,应该就能正常收到了。
内容的提问来源于stack exchange,提问作者Mizlul

