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

iOS应用首次运行无法接收FCM推送问题排查

iOS集成FCM推送异常排查

问题现象

  • App首次运行完成会员注册后无法接收推送通知,第二次启动App后推送可正常送达
  • 多次关闭重启App后再完成会员注册,同样无法接收推送,再次关闭重启App后推送恢复正常
  • 伴随异常:未收到推送直接进入首页后,后续可收到通知,但点击通知时didReceive回调不触发;即使多次重启设备,FCM token仅在会员注册时上报一次,暂未定位根因

现有业务流程

FCM token上报服务端流程

  1. 应用启动
  2. 将获取到的FCM token存储至UserDefaults
  3. 向用户申请通知权限,获取用户知情同意
  4. 进入会员注册流程
  5. 提交会员注册信息时,将会员信息与本地存储的FCM token一同上报服务端
  6. 会员注册流程完成

复现场景

  1. 首次运行App并完成会员注册:无法接收推送
  2. 首次运行完成注册后,关闭应用重新启动:可正常接收推送
  3. 多次关闭重启App后完成会员注册:无法接收推送
  4. 多次关闭重启后完成注册,再次关闭重启App:可正常接收推送

现有代码实现

注:用户通知权限申请逻辑位于独立ViewController中,由用户点击按钮触发

AppDelegate FCM核心逻辑

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    FirebaseApp.configure()
    UNUserNotificationCenter.current().delegate = self
    Messaging.messaging().delegate = self
    application.registerForRemoteNotifications()
    
    return true
}

func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
    messaging.token { token, _ in
        guard let token = token else {
            return
        }
        let defaults = UserDefaults.standard
        defaults.set(token, forKey:"userFCMToken")
        print("FIR Token : ", token)
    }
}

通知权限申请逻辑

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { success, _ in
        guard success else {
            print("用户未同意通知权限")
            self.registerViewPush()
            return
        }
        print("用户已同意通知权限")
        self.registerViewPush()
    }

UNUserNotificationCenterDelegate实现

@available(iOS 10, *)
extension AppDelegate: UNUserNotificationCenterDelegate {
// App前台运行时接收通知回调
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    print("willPresent App Push")
    let userInfo = notification.request.content.userInfo
    print("============willPresent================")
    print(userInfo)
    print("============================")
    completionHandler([[.alert, .badge, .sound]])
}

// 用户点击通知唤起App回调
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    print("didReceive ")
    
    let userInfo = response.notification.request.content.userInfo
    print("============OriginaldidReceive================")
    print(userInfo)
    print("============================")
    completionHandler()
}
}

环境信息

  • FirebaseMessaging版本:通过CocoaPods安装,版本为9.0.0
  • 推送接收成功时的payload示例:
[
AnyHashable("google.c.fid"): f9lzDdLFjkQpneQsfb-GxW,
AnyHashable("google.c.sender.id"): 900007830000,
AnyHashable("type"): CRING,
AnyHashable("aps"): {
    alert =     {
        body = "message";
        title = "message";
    };
    sound = default;
},
AnyHashable("title"): message,
AnyHashable("google.c.a.e"): 1,
AnyHashable("push"): N,
AnyHashable("body"): message,
AnyHashable("gcm.message_id"): 1657080600087000
]

可排查关键点

  • Token有效性与时序问题:加日志确认用户同意通知权限前,本地UserDefaults存储的FCM token是否为未绑定APNs权限的临时无效token。当前逻辑是App启动就立刻获取token存本地,用户同意权限后既不重新拉取新token,也不更新本地存储,注册时上报的是无效token自然推送失败;下次App重启时已获得通知权限,FCM才会生成有效token,但因为仅注册时上报一次,服务端仍存储旧token,直到触发上报才会恢复,和现有复现路径完全吻合。
  • APNs注册逻辑问题:当前在App刚启动、用户未同意权限时就直接调用registerForRemoteNotifications(),iOS在用户未授权通知的状态下不会返回有效的APNs device token,FCM拿不到有效APNs token就无法生成可正常下发推送的FCM token。用户同意权限后没有重新调用该方法触发APNs注册流程,必须等下次冷启动才能走通APNs注册、FCM绑定token的全流程。
  • Token回调逻辑问题:messaging(_:didReceiveRegistrationToken:)回调本身已经返回最新的fcmToken,当前实现又额外调用messaging.token异步拉取token,属于冗余逻辑,很容易出现时序问题:比如回调已返回新token,异步拉取时仍拿到旧值存入本地;另外需要加日志确认用户同意通知权限后,该token刷新回调是否会被触发,很多场景下权限状态变更后SDK不会主动触发回调,直到下次启动才会返回新token。
  • 通知点击回调不触发问题:当前未实现App杀死状态下冷启动的通知处理逻辑——如果App是被杀死状态,用户点击通知唤起,通知数据存储在didFinishLaunchingWithOptions的launchOptions参数中,不会走现有实现的didReceive回调;另外需要确认UNUserNotificationCenter.current().delegate = self的设置时机是否晚于回调触发时间点,如果冷启动时代理还未绑定就触发了通知事件,自然无法接收到回调。
  • Token上报策略问题:仅在会员注册时上报一次token的逻辑存在缺陷,FCM token并非永久固定,权限变更、APNs token刷新、SDK版本更新、用户重置设备隐私设置都会触发token刷新。正确逻辑应该是每次didReceiveRegistrationToken回调拿到新token时,先和本地存储的旧token比对,若不一致则更新本地存储,同时判断用户已完成注册的话,立刻将新token上报服务端,而非仅在注册节点上报一次。
  • SDK版本问题:FirebaseMessaging 9.0.0属于大版本迭代早期版本,存在数个已知的权限变更后token不刷新、回调不触发的bug,可核对对应版本的已知问题列表,或升级到同大版本的最新稳定小版本验证是否为SDK本身的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 13:18:33