iOS端FCM推送通知无法接收的问题排查求助
FCM正式推送无法送达的排查与修复建议
核心问题分析
测试消息可正常发送,但正式推送无送达记录,且间歇性出现APNS device token not set before retrieving FCM Token错误,说明FCM令牌未正确关联APNS令牌,导致正式推送时FCM无法通过APNS通道下发通知;推送活动发送量为0,大概率是目标令牌无效或未正确关联环境配置。
具体修复步骤
1. 修正APNS令牌类型与设置逻辑
当前代码中使用.unknown作为APNS令牌类型,这会导致FCM无法区分沙盒/生产环境。需根据当前运行环境指定正确类型,同时在设置APNS令牌后主动刷新FCM令牌,确保新令牌关联有效APNS信息:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // 根据环境选择APNS类型 let apnsType: MessagingAPNSTokenType = Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" ? .sandbox : .production Messaging.messaging().setAPNSToken(deviceToken, type: apnsType) // 设置后主动刷新FCM令牌 Messaging.messaging().token { token, error in if let error = error { print("获取FCM令牌失败: \(error.localizedDescription)") } else if let token = token { print("刷新后的FCM令牌: \(token)") // 同步更新服务器存储的令牌 let dataDict: [String: String] = ["token": token] NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict) } } }
2. 调整FCM初始化与通知注册顺序
确保FCM在APNS令牌获取完成后再生成令牌,可将通知权限请求与远程通知注册逻辑提前,避免FCM过早初始化:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 先配置通知相关 UNUserNotificationCenter.current().delegate = self UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .sound, .alert]) { granted, _ in guard granted else { return } DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } // 再初始化Firebase FirebaseApp.configure() let db = Firestore.firestore() Messaging.messaging().delegate = self return true }
3. 检查正式推送的环境与受众配置
- 确认Firebase控制台上传的APNS密钥为生产环境密钥(而非开发密钥),且Bundle ID完全匹配;
- 推送活动的目标受众需包含当前设备的有效FCM令牌,避免因令牌过期/未同步导致发送量为0;
- 正式推送需选择生产环境,测试消息默认使用沙盒环境,两者通道不互通。
4. 补充错误处理逻辑
添加远程通知注册失败的回调,排查APNS令牌获取失败的原因:
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("APNS令牌注册失败: \(error.localizedDescription)") }
额外检查点
- 确认应用签名使用生产证书,开发证书仅能用于沙盒环境推送;
- 检查
Info.plist中FirebaseAppDelegateProxyEnabled已设为NO(禁用Swizzling),且所有FCM代理方法均已手动实现; - 重启设备并重装应用,清除旧的令牌缓存后重新测试。
内容的提问来源于stack exchange,提问作者Jake Jake
相关产品推荐
相关产品推荐

