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

Firebase+SwiftUI推送通知失效问题求助

FCM推送通知突然无法接收的排查与修复方案

问题描述

已完成基于FCM的推送通知集成且此前功能正常,今日突然无法接收推送通知,Firebase后台已上传APN授权密钥,使用的代码如下:

import SwiftUI
import FirebaseCore
import FirebaseAuth
import Firebase 
import FirebaseMessagingInterop
import FirebaseMessaging
import UserNotifications

class AppDelegate: NSObject, UIApplicationDelegate {
  let gcmMessageIDKey = "gcm.message_id"

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
      FirebaseApp.configure()

      Messaging.messaging().delegate = self

      if #available(iOS 10.0, *) {
        // For iOS 10 display notification (sent via APNS)
        UNUserNotificationCenter.current().delegate = self

        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
          options: authOptions,
          completionHandler: {_, _ in })
      } else {
        let settings: UIUserNotificationSettings =
        UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
        application.registerUserNotificationSettings(settings)
      }

      application.registerForRemoteNotifications()
      return true
  }

  func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                   fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    if let messageID = userInfo[gcmMessageIDKey] {
      print("Message ID: \(messageID)")
    }

    print(userInfo)

    completionHandler(UIBackgroundFetchResult.newData)
  }
}

@main
struct YourApp: App {
// register app delegate for Firebase setup
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

var body: some Scene {
  WindowGroup {
    NavigationView {
       ContentView()
    }
  }
}
}

extension AppDelegate: MessagingDelegate {
  func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
    let deviceToken:[String: String] = ["token": fcmToken ?? ""]
      print("Device token: ", deviceToken) // This token can be used for testing notifications on FCM
  }
}

@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {

// Receive displayed notifications for iOS 10 devices.
func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent notification: UNNotification,
  withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
  let userInfo = notification.request.content.userInfo

  if let messageID = userInfo[gcmMessageIDKey] {
      print("Message ID: \(messageID)")
  }

  print(userInfo)

  // Change this to your preferred presentation option
  completionHandler([[.banner, .badge, .sound]])
}

  func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

  }

  func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

  }

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {
  let userInfo = response.notification.request.content.userInfo

  if let messageID = userInfo[gcmMessageIDKey] {
    print("Message ID from userNotificationCenter didReceive: \(messageID)")
  }

  print(userInfo)

  completionHandler()
}
}

排查与修复建议

  • 修复代码中的通知展示错误
    在iOS 10+的willPresent方法中,你传入了嵌套数组[[.banner, .badge, .sound]],这会导致前台通知无法正常展示,修正为:

    completionHandler([.banner, .badge, .sound])
    
  • 补全APNs注册错误日志
    当前didFailToRegisterForRemoteNotificationsWithError方法为空,添加日志输出可直接定位APNs注册问题:

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("APNs注册失败: \(error.localizedDescription)")
    }
    
  • 验证FCM Token有效性
    检查控制台输出的FCM Token是否正常更新,若未输出新Token,主动调用方法获取最新Token并确认:

    Messaging.messaging().token { token, error in
        if let error = error {
            print("获取FCM Token失败: \(error.localizedDescription)")
        } else if let token = token {
            print("当前FCM Token: \(token)")
        }
    }
    
  • 确认APN密钥与环境匹配
    检查Firebase后台的APN密钥是否过期,对应的Bundle ID与项目完全一致;同时确认推送环境(开发/生产)与当前App运行环境匹配,环境不匹配会导致推送无法送达。

  • 检查通知权限状态
    调用接口确认当前通知权限是否被用户关闭,若关闭需引导用户重新开启:

    UNUserNotificationCenter.current().getNotificationSettings { settings in
        print("当前通知权限: \(settings.authorizationStatus.rawValue)")
    }
    
  • 查看Firebase推送记录
    前往Firebase控制台「云消息传递」页面,查看推送的送达状态与错误详情,比如Token失效、设备离线等具体原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:53:32