如何在SwiftUI后台实现Firebase自动通讯消息通知?
问题:SwiftUI + Firebase聊天应用实现新消息自动推送通知
我正在用SwiftUI和Firebase开发聊天应用,希望用户收到新消息时自动显示推送通知。目前已经集成了Firebase Cloud Messaging(FCM),但无法自动触发通知。需要实现收到消息时自动发送推送通知,找不到相关的Swift+Firebase后台推送教程。
现有FCM配置代码
import SwiftUI import FirebaseCore import FirebaseMessaging @main struct SimplePhoneApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { Main() } } } class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { FirebaseApp.configure() UNUserNotificationCenter.current().delegate = self let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization( options: authOptions, completionHandler: { _, _ in } ) application.registerForRemoteNotifications() Messaging.messaging().delegate = self return true } func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) async -> UIBackgroundFetchResult { return .noData } } extension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions { let userInfo = notification.request.content.userInfo print(userInfo) return [[.alert, .sound]] } func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async { let userInfo = response.notification.request.content.userInfo print(userInfo) } func application(application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async -> UIBackgroundFetchResult { // Messaging.messaging().apnsToken = deviceToken print(userInfo) return UIBackgroundFetchResult.newData } } extension AppDelegate: MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { print("Firebase registration token: \(String(describing: fcmToken))") let dataDict: [String: String] = ["token": fcmToken ?? ""] NotificationCenter.default.post( name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict ) } }
本地通知测试代码(可正常运行)
func scheduleCustomNotification() { let content = UNMutableNotificationContent() content.title = "New Message" content.body = "You have a new message from John Doe." let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) // Schedule notification to appear after 5 seconds let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) { error in if let error = error { print("Error scheduling notification: \(error)") } else { print("Custom notification scheduled successfully.") } } }
解决方案步骤
1. 修正FCM消息接收逻辑
你的代码里存在重复的didReceiveRemoteNotification方法,且未处理消息触发通知的逻辑。统一处理FCM消息,收到新消息时直接调用本地通知发送:
// 替换原有的didReceiveRemoteNotification方法 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) async -> UIBackgroundFetchResult { // 解析FCM消息中的标题和内容 let messageTitle = userInfo["title"] as? String ?? "新消息" let messageBody = userInfo["body"] as? String ?? "你收到一条新消息" // 发送本地通知 sendLocalNotification(title: messageTitle, body: messageBody) return .newData } // 新增本地通知发送方法 private func sendLocalNotification(title: String, body: String) { let content = UNMutableNotificationContent() content.title = title content.body = body content.sound = .default content.badge = UIApplication.shared.applicationIconBadgeNumber + 1 as NSNumber // 立即触发通知 let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false) let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) { error in if let error = error { print("发送通知失败: \(error)") } } }
2. 配置FCM后台消息格式
确保Firebase发送的消息包含必要字段,后台静默消息需添加content_available: true,保证应用在后台也能接收处理:
示例FCM请求体(可通过Firebase Admin SDK或Postman发送):
{ "to": "用户的FCM_TOKEN", "content_available": true, "notification": { "title": "新消息", "body": "张三给你发了一条消息" }, "data": { "title": "新消息", "body": "张三给你发了一条消息", "chatId": "12345" } }
3. 确认应用权限与配置
- 在
Info.plist中添加UIBackgroundModes数组,包含remote-notification项,开启后台推送权限; - 确保
GoogleService-Info.plist已正确导入项目; - 必须使用真机测试,模拟器无法接收FCM推送。
4. 前台消息处理优化
如果应用处于前台,willPresent方法已返回.alert和.sound,若需自定义样式,可在该方法内调用sendLocalNotification方法实现。
内容的提问来源于stack exchange,提问作者Bart Van de Veire
相关产品推荐
相关产品推荐

