使用Invertase实现React Native iOS设备FCM推送失败排查
解决iOS端Invertase FCM推送无响应的问题
首先明确:你完全不需要依赖zo0r/react-native-push-notification或wix/react-native-notifications这类第三方库,Invertase的@react-native-firebase/messaging本身就足够处理iOS的推送通知,那些库只是用来扩展本地通知的管理能力,基础的FCM推送完全可以靠官方库实现。
你能获取到token但收不到通知,大概率是iOS端的配置或代码逻辑有遗漏,下面一步步排查:
一、必须补全的iOS配置项
这些是iOS推送的基础门槛,缺一不可:
1. Xcode项目配置
- 打开你的iOS项目,在
Signing & Capabilities标签下,添加Push Notifications能力(确保自动生成的配置正确) - 同时添加
Background Modes能力,勾选Remote notifications(后台接收推送需要) - 确认你的App ID在苹果开发者后台已经启用了
Push Notifications服务
2. Firebase控制台配置
- 进入Firebase项目设置 →
Cloud Messaging标签,找到iOS应用的配置区域 - 上传对应的APNs证书(开发/生产环境要区分),或者使用Token验证(推荐,更灵活):
- 从苹果开发者后台生成APNs Auth Key,上传到Firebase
- 填写对应的Team ID和Key ID
3. iOS系统权限细节
- iOS 10+需要用户明确授权通知权限,
requestPermission要包含必要的选项:await messaging().requestPermission({ alert: true, badge: true, sound: true, }); - 光请求权限还不够,必须调用系统API注册远程通知:
// 请求权限后,调用这个方法触发系统注册 await messaging().registerDeviceForRemoteNotifications();
二、代码端的必要逻辑处理
除了获取token,你还需要处理不同状态下的通知接收:
1. 完整的初始化代码示例
import messaging from '@react-native-firebase/messaging'; import { Platform } from 'react-native'; // 应用启动时初始化推送 const setupFCM = async () => { // 1. 请求权限 const authStatus = await messaging().requestPermission({ alert: true, badge: true, sound: true, }); const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL; if (enabled) { // 2. 注册远程通知(iOS必须) if (Platform.OS === 'ios') { await messaging().registerDeviceForRemoteNotifications(); } // 3. 获取token const token = await messaging().getToken(); console.log('FCM Token:', token); // 4. 监听前台通知接收 messaging().onMessage(async remoteMessage => { console.log('前台收到通知:', remoteMessage); // 如果需要在前台显示通知,iOS需要手动创建本地通知(默认前台不弹窗) // 可以用@react-native-firebase/notifications库来创建,或者原生代码 }); // 5. 监听后台通知点击 messaging().onNotificationOpenedApp(remoteMessage => { console.log('后台点击通知:', remoteMessage); // 处理跳转逻辑 }); // 6. 监听应用杀死状态下的通知点击 const initialNotification = await messaging().getInitialNotification(); if (initialNotification) { console.log('杀死状态点击通知:', initialNotification); } } }; // 在App组件的useEffect里调用 useEffect(() => { setupFCM(); }, []);
2. iOS原生层(AppDelegate)配置
如果是React Native 0.60+,react-native-firebase会自动配置,但如果有问题,手动检查AppDelegate.m:
#import <Firebase.h> #import <UserNotifications/UserNotifications.h> #import <RNFBApp/RNFBAppModule.h> #import <RNFBMessaging/RNFBMessagingModule.h> @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [FIRApp configure]; // 配置UNUserNotificationCenter代理 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; // ...其他原有代码 return YES; } // iOS 10+:前台接收通知时的回调 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge); } // iOS 10+:通知点击回调 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler { [RNFBMessagingModule didReceiveNotificationResponse:response]; completionHandler(); } // 处理APNs token注册 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [RNFBMessagingModule didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { [RNFBMessagingModule didFailToRegisterForRemoteNotificationsWithError:error]; } @end
三、推送Payload的格式要求
iOS对FCM的payload有严格要求,必须包含aps字段,否则系统不会触发通知。示例正确的payload:
// Firebase Admin SDK发送示例 const message = { token: 'DEVICE_TOKEN', notification: { title: '测试通知', body: '这是iOS测试推送', }, apns: { payload: { aps: { alert: { title: '测试通知', body: '这是iOS测试推送', }, badge: 1, sound: 'default', }, }, }, }; await admin.messaging().send(message);
注意:如果只发notification字段,FCM会自动转换为aps格式,但如果是data消息,iOS后台/杀死状态下不会自动弹窗,需要你在代码里手动处理。
最后排查点
- 确认测试设备的iOS版本,iOS 14+需要用户允许通知(设置→你的App→通知)
- 区分开发环境和生产环境:开发用APNs开发证书,生产用生产证书,Firebase控制台要对应配置
- 检查Firebase Admin SDK的版本,确保和客户端库版本兼容
内容的提问来源于stack exchange,提问作者Simon




