You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 12:18:10