Swift模拟器中FCM Token始终为nil,APNS Token未指定问题求助
解决iOS模拟器中FCM Token为nil的问题
核心问题分析
你遇到的Declining request for FCM Token since no APNS Token specified提示,本质是FCM需要依赖APNS Token才能生成自己的推送令牌,但当前模拟器未成功获取到APNS Token,同时代码缺少关键的APNS注册回调处理。
具体修复步骤
1. 添加APNS注册回调,将Token传递给FCM
FCM必须拿到APNS Token才能生成FCM Token,你需要通过SwiftUI的UIApplicationDelegateAdaptor集成回调逻辑:
修改主应用类:
@main struct ML2V_IOSApp: App { @StateObject var viewModel = AuthViewModel() @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate let pushNotificationManager = PushNotificationManager() init(){ FirebaseApp.configure() FirebaseConfiguration.shared.setLoggerLevel(.max) pushNotificationManager.registerForPushNotifications() } var body: some Scene { WindowGroup { ContentRooting().environmentObject(viewModel) } } } class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // 将APNS Token传递给FCM Messaging.messaging().apnsToken = deviceToken } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("APNS注册失败:\(error.localizedDescription)") } }
同时删除主应用中重复的requestNotificationAuthorization()函数,避免权限请求冲突。
2. 调整FCM Token的更新时机
不要在getUser()中同步获取fcmToken,而是在FCM的回调中处理Firestore更新(FCM Token是异步生成的):
修改PushNotificationManager的回调方法:
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { guard let token = fcmToken else { print("FCM Token为空") return } print("FCM Token: \(token)") // 调用ViewModel更新Firestore if let rootVC = UIApplication.shared.windows.first?.rootViewController { let viewModel = rootVC.environmentObject(AuthViewModel.self) Task { await viewModel.updateFCMToken(token: token) } } }
在AuthViewModel中添加专门的更新方法:
func updateFCMToken(token: String) async { guard let useruid = Auth.auth().currentUser?.uid else { print("用户未登录,无法更新FCM Token") return } let db = Firestore.firestore() let userDocRef = db.collection("users").document(useruid) do { try await userDocRef.setData(["fcm": token], merge: true) print("FCM token更新成功") } catch { print("更新FCM Token失败:\(error.localizedDescription)") } }
3. 模拟器推送支持配置
如果坚持用模拟器测试,需满足:
- 使用Xcode 11+版本
- 模拟器iOS版本≥13.0
- 通过
Hardware > Push Notification发送测试推送,触发APNS Token生成 - 确认GoogleService-Info.plist中
APNS_ENVIRONMENT字段为development(开发环境)
4. 证书与项目配置检查
- 确认Apple开发者平台的APNS证书(开发/生产)已正确上传到Firebase控制台
- 检查Xcode项目
Signing & Capabilities中已添加Push Notifications,并在Background Modes中勾选Remote notifications - 确保GoogleService-Info.plist的Bundle ID与开发者平台、Xcode项目一致
关键注意点
- iOS模拟器的APNS支持有限,优先用真机测试推送功能
- FCM Token会不定期刷新,必须在
didReceiveRegistrationToken回调中处理更新,不能只获取一次 - 权限请求只需调用一次,重复调用可能被系统忽略
内容的提问来源于stack exchange,提问作者Windows Frame
相关产品推荐
相关产品推荐

