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

Flutter iOS真机调用FirebaseMessaging.getAPNSToken()返回null

Flutter iOS真机无法获取APNS Token,模拟器正常的问题

问题现象

调用FirebaseMessaging.instance.getToken()时触发firebase_messaging/apns-token-not-set错误,转而调用FirebaseMessaging.instance.getAPNSToken():

  • iPhone 15模拟器能正常获取APNS Token
  • 有线连接Mac的真机、TestFlight安装的同一真机均返回null

代码实现

初始化通知的核心代码:

Future<void> initNotifications() async {
    await FirebaseMessaging.instance.setAutoInitEnabled(true);

    final permissionRequest = await FirebaseMessaging.instance.requestPermission(
      alert: true,
      announcement: false,
      badge: true,
      carPlay: false,
      criticalAlert: false,
      provisional: false,
      sound: true,
    );

    if (permissionRequest.authorizationStatus == AuthorizationStatus.authorized) {
      String? fcmToken;

      if (Platform.isIOS) {
        String? apnsToken = await FirebaseMessaging.instance.getAPNSToken();

        if (apnsToken != null) {
          debugPrint("APNS Token: $apnsToken");
          fcmToken = await FirebaseMessaging.instance.getToken();
          debugPrint("FCM Token: $fcmToken");
        } else {
          debugPrint("APNS Token not available, waiting ...");

          await Future<void>.delayed(
            const Duration(
              seconds: 3,
            ),
          );

          apnsToken = await FirebaseMessaging.instance.getAPNSToken();

          if (apnsToken != null) {
            debugPrint("APNS Token: $apnsToken");
            fcmToken = await FirebaseMessaging.instance.getToken();
            debugPrint("FCM Token: $fcmToken");
          } else {
            debugPrint("APNS Token not available, trying to get FCM token anyway ...");
            
            try {
              fcmToken = await FirebaseMessaging.instance.getToken();
            } catch (err) {
              debugPrint("FCM Token not available ($err)");
            }
          }
        }

      } else {
        fcmToken = await FirebaseMessaging.instance.getToken();
        debugPrint("FCM Token: $fcmToken");
      }
    } else {
      debugPrint("Notifications not authorized");
    }
}

main.dart中的调用逻辑:

WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);
await FireBaseNotifications().initNotifications();

已完成的配置

  • Xcode:启用Push Notifications;Background Modes勾选Background fetch、Remote notifications
  • Firebase控制台:已上传开发、生产环境的APNs证书
  • 依赖版本:
    firebase_core: ^2.20.0
    firebase_messaging: ^14.7.2
    

排查与解决建议

1. 证书与Provisioning Profile校验

  • 确认真机使用的Provisioning Profile包含Push Notifications权限,且对应证书与Firebase控制台上传的完全一致(开发环境用开发证书,TestFlight/生产用生产证书)
  • 检查Xcode中Signing & Capabilities的Provisioning Profile是否有效、未过期,Bundle ID与Firebase控制台的iOS应用完全匹配(大小写一致)

2. 系统权限检查

  • 真机端进入「设置→通知→你的应用」,确认通知权限已完全开启(包括允许通知、横幅/声音等选项)
  • 若用户首次弹窗时拒绝了权限,代码中未处理重新请求逻辑,需手动开启权限后重试

3. APNs环境匹配

  • Debug调试(有线连接)对应开发APNs环境,TestFlight/Release对应生产环境,确保Firebase控制台中对应环境的证书已正确上传并激活
  • 检查DefaultFirebaseOptions中的iOS配置,apnsEnvironment是否与当前运行环境匹配(开发环境设为APNSEnvironment.development,生产设为APNSEnvironment.production)

4. 代码逻辑优化

  • 无需手动获取APNS Token再请求FCM Token,FCM SDK会自动处理APNS Token的绑定,改用监听onTokenRefresh事件更可靠:
    // 监听Token刷新
    FirebaseMessaging.instance.onTokenRefresh.listen((newToken) {
      debugPrint("FCM Token refreshed: $newToken");
      // 将Token同步到服务器
    });
    
    // 首次获取Token
    String? initialToken = await FirebaseMessaging.instance.getToken();
    if (initialToken != null) {
      debugPrint("Initial FCM Token: $initialToken");
    }
    
  • 固定延迟重试的逻辑不可靠,APNS Token由系统异步返回,监听回调是更合理的方式

5. Xcode深层配置检查

  • 手动确认Info.plist中已添加UIBackgroundModes并包含remote-notification(勾选Background Modes后Xcode会自动添加,可右键Info.plist→Open As→Source Code查看)
  • 确保Xcode项目的Build Settings中,ENABLE_BITCODE设为NO(部分旧版本Firebase SDK对此有要求)

6. 网络与系统环境

  • 真机需正常连接苹果APNS服务器,避免使用代理或处于受限网络环境
  • 确保iOS系统版本在13.0以上,尽量使用较新版本系统,避免SDK与系统兼容性问题

内容的提问来源于stack exchange,提问作者Patrick

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 01:28:13