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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:20:53