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

Flutter iOS版FCM推送:Release模式下Device Token为空求助

Flutter FCM iOS Release模式Device Token为空的解决方案

针对你遇到的Flutter应用FCM推送在iOS真机Release模式下Device Token为空的问题,可按以下步骤排查修复:

1. 确认推送证书与配置文件有效性

  • 检查Release环境的APNs推送证书是否在Apple Developer后台有效,且绑定的Bundle ID与应用完全一致
  • 确认Release版Provisioning Profile已包含Push Notification权限,并且是最新生成的,重新下载后导入Xcode

2. 修正AppDelegate.swift配置

当前代码存在几处可能导致Token获取失败的问题,建议修改为:

import UIKit
import Flutter
import Firebase
import FirebaseMessaging

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, MessagingDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        FirebaseApp.configure()
        
        // 设置通知与FCM代理
        if #available(iOS 10.0, *) {
            UNUserNotificationCenter.current().delegate = self
            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { granted, error in
                if granted {
                    DispatchQueue.main.async {
                        application.registerForRemoteNotifications()
                    }
                }
            }
        } else {
            let settings: UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()
        }
        
        // 设置FCM代理
        Messaging.messaging().delegate = self
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    
    override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
        print("APNs Token: \(deviceToken)")
        super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
    }
    
    // 捕捉Token获取失败的错误信息
    override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Token获取失败: \(error.localizedDescription)")
    }
    
    // FCM Token更新回调
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("FCM Token: \(fcmToken ?? "空")")
        // 可在此将Token传递给Flutter侧
    }
}

关键修改点:

  • 直接将UNUserNotificationCenter的delegate设为self,移除不安全的as?强制转换
  • 添加通知权限请求逻辑,确保用户授权后再注册远程通知
  • 实现MessagingDelegate并设置代理,直接监听FCM Token的生成与更新
  • 添加didFailToRegisterForRemoteNotificationsWithError方法,排查Token获取失败的具体原因

3. 完善Info.plist配置

确保添加后台推送模式支持:

<key>UIBackgroundModes</key>
<array>
    <string>remote-notification</string>
</array>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>

同时确认GoogleService-Info.plist是Release环境对应的文件,而非Debug版本。

4. Xcode编译设置检查

  • 在Signing & Capabilities中确认Push Notifications已添加,且Release环境下处于启用状态
  • 检查Build Settings中Enable Background Modes为勾选状态
  • 确认Code Signing Identity使用的是正确的Release证书,与Provisioning Profile匹配

5. Flutter侧代码优化

确保firebase_messaging包为最新版本,并在Flutter代码中正确请求权限与获取Token:

import 'package:firebase_messaging/firebase_messaging.dart';

void initFCM() async {
  FirebaseMessaging messaging = FirebaseMessaging.instance;
  
  // 请求通知权限
  NotificationSettings settings = await messaging.requestPermission(
    alert: true,
    badge: true,
    sound: true,
  );
  
  if (settings.authorizationStatus == AuthorizationStatus.authorized) {
    // 获取FCM Token
    String? token = await messaging.getToken();
    print("Flutter侧FCM Token: $token");
  }
}

完成以上步骤后,重新打包Release版本测试,通过Xcode控制台查看日志,定位是否还有其他错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 08:34:44