React Native中iOS15获取FCM Token失败,iOS17及以上正常
问题原因分析
- APNS Token生成时机差异:iOS 15及更早版本中,FCM Token的生成依赖APNS Token,但APNS Token的下发是异步过程,系统需要时间完成权限验证和Token生成。当前代码在获取FCM权限后直接同步调用
getToken(),此时APNS Token可能尚未就绪,导致报错。而iOS 17+优化了APNS Token的生成流程,能快速完成与FCM的关联,因此无此问题。 - 缺少APNS Token监听逻辑:现有代码未监听APNS Token的更新事件,无法在Token就绪时触发FCM Token的获取,仅依赖同步调用,在低版本iOS中极易失败。
- 权限流程不兼容:iOS 15中,推送权限授权完成后,系统不会立即生成APNS Token,需要等待系统回调触发,直接调用
getToken()会因缺少APNS Token而失败。
解决建议
1. 调整Token获取逻辑,依赖APNS Token就绪状态
修改权限请求和Token获取流程,针对iOS版本做兼容,确保在APNS Token生成后再获取FCM Token:
const getFcmToken = async (apnsToken) => { try { let fcmToken = await AsyncStorage.getItem('fcmToken'); console.log(fcmToken, 'the old token'); if (!fcmToken || fcmToken === null || fcmToken === '') { console.log('No FCM token found, generating a new one...'); // 传入APNS Token生成FCM Token(适配iOS 15及以下) const tokenOptions = apnsToken ? { apnsToken } : {}; fcmToken = await messaging().getToken(tokenOptions); if (fcmToken) { console.log(fcmToken, 'the newly generated token'); await AsyncStorage.setItem('fcmToken', fcmToken); } } } catch (error) { console.log(error, 'error in retrieving or generating FCM token'); } }; export async function requestUserPermission() { const authStatus = await messaging().requestPermission(); const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL; if (enabled) { console.log('Authorization status:', authStatus); // 全局监听FCM Token刷新,自动更新本地存储 messaging().onTokenRefresh(async (fcmToken) => { console.log('FCM Token refreshed:', fcmToken); await AsyncStorage.setItem('fcmToken', fcmToken); }); const iosVersion = Platform.OS === 'ios' ? parseInt(Platform.Version, 10) : 0; if (iosVersion <= 15) { // 针对iOS 15及以下,先尝试获取APNS Token const apnsToken = await messaging().getAPNSToken(); if (apnsToken) { await getFcmToken(apnsToken); } else { // 若APNS Token未就绪,监听其刷新事件 messaging().onAPNSTokenRefresh(async (newApnsToken) => { await getFcmToken(newApnsToken); }); } } else { // iOS 16+直接调用getToken即可 await getFcmToken(); } } }
2. 确保原生端APNS Token配置正确
在iOS的AppDelegate.swift中,需将APNS Token传递给Firebase Messaging,确保FCM能正确关联APNS Token:
import FirebaseMessaging func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // 将APNS Token赋值给Firebase Messaging Messaging.messaging().apnsToken = deviceToken super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken) }
3. 检查项目配置
- 确认Xcode项目的Capabilities中已开启
Push Notifications。 - 确保APNS证书(开发/生产环境)配置正确,且与当前构建模式(Debug/Release)匹配。
- 验证
react-native-firebase/messaging版本为最新稳定版,避免版本兼容问题。
4. 关于ATT权限的说明
ATT权限主要用于广告追踪,与推送Token的获取无直接关联。但如果你的应用在iOS 15中请求了ATT权限,需确保ATT权限请求在推送权限请求之前,避免系统权限弹窗顺序影响用户授权意愿,但这不是导致Token为null的直接原因。
内容的提问来源于stack exchange,提问作者dawid_Pascal
相关产品推荐
相关产品推荐

