FCM数据消息触发本地通知异常:App终止时不显示问题求助
问题原因分析
当你的App处于**完全终止(被用户划掉/系统杀死)**状态时,FCM的纯数据负载消息根本不会被系统传递到你的App里——这是iOS系统的机制限制:只有包含notification字段的FCM消息(纯通知消息或通知+数据的混合消息),才会在App终止时被系统接管并展示通知;而纯数据消息在App终止时,系统不会主动唤醒你的App去执行didReceiveRemoteNotification方法,自然也就无法触发你代码里的本地通知逻辑了。
简单说:你的didReceiveRemoteNotification只有在App前台/后台活跃(或挂起)时才会被调用,App终止时这个方法根本没机会执行。
解决方案
要实现App终止状态下也能触发本地通知,你需要调整FCM消息的发送结构,同时修改App端的处理逻辑:
1. 发送FCM混合消息(通知+数据负载)
在服务器端发送FCM消息时,同时包含notification和data字段:
{ "to": "你的设备Token", "notification": { "title": "默认通知标题", "body": "默认通知内容" }, "data": { "customKey1": "你需要的自定义数据", "customKey2": "更多自定义内容" } }
这样做的好处是:
- App终止时,系统会直接展示
notification字段对应的通知(不需要App参与); - 用户点击通知后,App会被唤醒,此时你可以拿到
data里的自定义内容做后续处理。
2. 修改App端的启动逻辑
在didFinishLaunchingWithOptions方法中,检查App是否是通过点击FCM通知唤醒的,如果是,就可以获取数据并触发自定义本地通知(或者直接处理业务逻辑):
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 初始化通知相关配置(确保已经设置UNUserNotificationCenter代理) UNUserNotificationCenter.current().delegate = self let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { granted, error in // 处理权限申请结果 } application.registerForRemoteNotifications() // 检查是否是远程通知唤醒App if let remoteNotificationData = launchOptions?[.remoteNotification] as? [AnyHashable: Any] { // 从data字段里取出自定义数据,生成本地通知 let notificationContent = UNMutableNotificationContent() notificationContent.title = remoteNotificationData["customTitle"] as? String ?? "默认标题" notificationContent.body = remoteNotificationData["customBody"] as? String ?? "默认内容" notificationContent.sound = .default let request = UNNotificationRequest( identifier: UUID().uuidString, content: notificationContent, trigger: nil ) UNUserNotificationCenter.current().add(request) { error in if let error = error { print("添加本地通知失败:\(error)") } } } return true }
3. 补充:确保后台权限配置正确
别忘了在Xcode的Capabilities中开启Background Modes,并勾选Remote notifications——这是App后台接收FCM数据消息的必要前提。
额外说明
- 如果你不想让系统默认展示通知,只想用自定义本地通知,那可以在
notification字段里设置一些无意义的内容(比如空标题空内容),然后在App被唤醒后,用data里的内容生成你想要的本地通知; - 用户点击通知后的逻辑,依然可以在
userNotificationCenter(_:didReceive:withCompletionHandler:)方法中处理,不管App是从后台还是终止状态被唤醒,这个方法都会被调用。
内容的提问来源于stack exchange,提问作者Ali Akkawi
相关产品推荐
相关产品推荐

