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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:05:02