Swift中获取FCM Token先报错后成功的问题及正确实现方法
问题分析与解决
原因说明
报错No APNS token specified before fetching FCM Token的核心逻辑是:你调用FCM Token获取方法时,苹果推送服务(APNs)的token还未完成生成或传递给Firebase Messaging。
FCM在iOS平台依赖APNs token生成对应FCM Token,当你提前触发Messaging.messaging().token调用时,APNs的初始化流程还没走完,就会抛出这个错误。后续APNs token生成完成后,Firebase Messaging会自动重试获取FCM Token,所以你会看到之后成功拿到token的日志。
解决方案
要避免这个错误,需确保在APNs token就绪后再处理FCM Token获取,或者通过监听回调处理Token更新:
方法1:在APNs Token就绪后主动获取
在AppDelegate的didRegisterForRemoteNotificationsWithDeviceToken方法中,先将APNs token传递给Firebase Messaging,再获取FCM Token:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // 传递APNs token给Firebase Messaging Messaging.messaging().apnsToken = deviceToken // 此时获取FCM Token Messaging.messaging().token { token, error in if let error = error { print("获取FCM Token失败: \(error)") } else if let token = token { print("FCM Token: \(token)") } } }
方法2:监听FCM Token更新回调
通过MessagingDelegate监听Token的生成与更新,无需主动调用获取方法:
- 让
AppDelegate遵循MessagingDelegate协议:
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate { // ... 其他原有代码 }
- 在启动方法中配置代理并请求推送权限:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { FirebaseApp.configure() Messaging.messaging().delegate = self // 请求用户推送权限 UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in guard granted else { return } DispatchQueue.main.async { application.registerForRemoteNotifications() } } return true }
- 实现Token更新回调方法:
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { guard let token = fcmToken else { return } print("Firebase注册Token: \(token)") // 在这里处理Token,比如上传到你的业务服务器 }
额外注意点
- 确保已在苹果开发者后台配置推送证书,并同步上传到Firebase控制台。
- 必须使用真机测试,模拟器无法生成APNs token,会导致FCM Token获取失败。
内容的提问来源于stack exchange,提问作者Usman
相关产品推荐
相关产品推荐

