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

iOS与FCM问题:首次启动无法收消息,切换前后台或重启后恢复

iOS FCM首次启动无法接收消息,重启/前后台切换后恢复正常?

各位Stack Overflow社区成员好!我在iOS集成FCM时遇到一个奇怪的问题:首次启动应用无法接收FCM消息,但如果关闭应用重新打开,或者把应用切换到后台再回到前台,就能突然收到之前所有的消息,之后应用运行期间接收消息都正常,只有首次启动的这个场景有异常。

目前我发现只有将FirebaseInstanceID降级到2.0.0才能解决该问题,当前使用的Firebase Pod版本如下:

  • Firebase 4.13.0
  • FirebaseAnalytics 4.2.0
  • FirebaseAuth 4.6.1
  • FirebaseCore 4.0.20
  • FirebaseCrash 2.0.2
  • FirebaseInstanceID 2.0.0
  • FirebaseMessaging 2.2.0

使用的Xcode版本为9.3(9E145)。

我的AppDelegate的didFinishLaunchingWithOptions方法中包含以下代码:

Messaging.messaging().delegate = self
Messaging.messaging().shouldEstablishDirectChannel = true
FirebaseApp.configure()
application.registerForRemoteNotifications()

同时实现了APNs token注册的方法:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    print("APNs token retrieved: \(deviceToken)")
    Messaging.messaging().apnsToken = deviceToken
}

还扩展了AppDelegate遵循MessagingDelegate协议:

extension AppDelegate : MessagingDelegate {
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        // 这里是处理FCM token的逻辑
    }
    func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
        // 这里是接收FCM消息的逻辑
    }
}

请问这是FCM的常见Bug,还是我的代码实现存在错误?非常感谢!


解答

嘿,这个问题我之前在旧版本Firebase里碰到过!首先可以明确的是,这大概率是旧版本FirebaseInstanceID和Messaging配合的已知Bug,不是你的代码实现问题——毕竟你已经通过降级InstanceID解决了问题,这也侧面验证了版本兼容的问题。

具体来说,在Firebase 4.x系列的部分版本中,FirebaseInstanceID和FirebaseMessaging的初始化时序存在问题:首次启动时,FCM的直接通道(就是你设置的shouldEstablishDirectChannel = true)可能在APNs token绑定完成前就尝试建立,导致通道初始化失败,无法接收消息。而重启或者前后台切换时,APNs token已经被持久化,通道能正常建立,所以消息就都过来了。

除了降级FirebaseInstanceID到2.0.0,你还有几个可选的解决方案:

  • 调整代码初始化顺序:把FirebaseApp.configure()放在最前面,再设置delegate和直接通道,最后注册远程通知。这样能确保Firebase核心服务初始化完成后,再配置Messaging相关的参数,避免时序问题:
    FirebaseApp.configure()
    Messaging.messaging().delegate = self
    Messaging.messaging().shouldEstablishDirectChannel = true
    application.registerForRemoteNotifications()
    
  • 升级到更高版本的Firebase:Firebase在后续的版本(比如5.x及以上)已经修复了这个初始化时序的Bug,如果你能兼容更高版本的SDK,升级后这个问题应该会自动消失。不过升级前记得测试现有功能的兼容性,避免其他潜在问题。
  • 手动触发通道重建:如果暂时不能升级或降级,可以在didReceiveRegistrationToken方法里手动调用Messaging.messaging().shouldEstablishDirectChannel = true,确保在FCM token获取到后重新建立通道:
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        // 处理token逻辑
        Messaging.messaging().shouldEstablishDirectChannel = true
    }
    

另外,还要确认一下你的APNs配置是否正确——比如推送证书是否有效,App ID是否开启了推送权限,但从你重启后能正常接收消息来看,这部分应该没问题。

总的来说,这个是旧版本Firebase的已知问题,调整初始化顺序或者升级SDK都是比长期停留在旧版本更好的解决方案,毕竟旧版本可能还有其他安全或功能上的缺陷。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:34:50