iOS 11应用集成Firebase推送通知失败求助
结合iOS 11的特性和Firebase推送的集成要求,我帮你梳理几个最容易遗漏的代码环节:
未正确请求推送权限
iOS 11及以后依赖UserNotifications框架,你需要在App启动时主动请求用户授权推送权限,同时注册远程通知。确保代码里有这两段关键逻辑(放在didFinishLaunchingWithOptions里):import UserNotifications import FirebaseMessaging // 请求推送权限 UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in guard granted else { return } DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } }这里要注意必须在用户授权后调用
registerForRemoteNotifications(),否则无法获取设备令牌。Firebase初始化时机错误
一定要在处理推送相关逻辑之前初始化Firebase,也就是FirebaseApp.configure()要放在didFinishLaunchingWithOptions的最前面(至少在推送代码之前),否则Messaging服务无法正常绑定:func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 先初始化Firebase FirebaseApp.configure() // 再处理推送权限、代理设置等 // ... return true }未将设备令牌传给Firebase
当系统返回设备令牌时,你需要把它同步给Firebase Messaging,否则Firebase无法识别你的设备。确保实现这个UIApplicationDelegate方法:func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { Messaging.messaging().apnsToken = deviceToken }未设置Messaging代理
iOS 11下需要设置Messaging的代理来监听令牌更新,否则可能出现令牌失效但Firebase未同步的情况。在didFinishLaunchingWithOptions里添加:Messaging.messaging().delegate = self然后让AppDelegate遵循
MessagingDelegate协议,并实现令牌更新方法:extension AppDelegate: MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { print("FCM token updated: \(fcmToken ?? "")") // 这里可以把token上传到你的服务器(如果需要) } }前台通知未处理
如果你的App在前台运行时无法收到通知弹窗,那是因为iOS默认不会在前台显示通知。需要实现UNUserNotificationCenterDelegate的方法来强制显示:extension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { // 允许前台显示通知弹窗、声音和角标 completionHandler([.alert, .sound, .badge]) } }别忘了在
didFinishLaunchingWithOptions里设置通知中心的代理:UNUserNotificationCenter.current().delegate = self
内容的提问来源于stack exchange,提问作者D. Finna

