Swift 4中iOS应用未运行时如何接收FCM远程消息?
解决iOS App未运行时接收Firebase主题消息并触发推送的问题
嘿,我来帮你搞定这个问题!你现在的情况是App在前台/后台能收消息,但未运行时不行,核心问题出在推送Payload格式和AppDelegate的必要配置上,还有一些容易忽略的权限设置,我一步步给你讲:
1. 修正推送Payload(最关键的一步)
你当前的Postman请求只有data和content_available字段,但iOS的APNs(Apple推送通知服务)在App未运行时,只会处理包含aps字段(或Firebase封装的notification字段)的推送请求——纯数据消息不会触发通知弹窗,只会在App启动后把数据传给你。
如果你希望App未运行时直接弹出通知,把你的Postman请求改成这样:
{ "to": "/topics/my-topic", "content_available": true, "notification": { "title": "你的通知标题", "body": "some message..", "sound": "default", "badge": 0 }, "data": { "message": "some message.." } }
notification字段是Firebase用来封装APNs所需的aps内容,APNs会直接用这个字段展示通知;- 如果需要静默接收数据再手动触发本地推送,你可以保留纯data格式,但必须在App启动时处理数据并创建本地通知(后面会讲)。
2. 完善AppDelegate的必要方法
你现在只实现了willPresent方法(处理前台收到通知的情况),但未运行时的推送需要另外两个关键方法:
2.1 处理App从推送启动的情况
在didFinishLaunchingWithOptions里,检查是否是从远程推送启动的App,如果是,取出数据并触发本地推送(如果需要):
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { FirebaseApp.configure() // 请求推送权限(必须!第一次启动App时会弹窗让用户授权) UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in guard granted else { return } DispatchQueue.main.async { application.registerForRemoteNotifications() } } // 检查是否从推送启动App if let remoteNotification = launchOptions?[.remoteNotification] as? [String: Any] { let message = remoteNotification["message"] as? String ?? "" // 触发本地推送 let content = UNMutableNotificationContent() content.title = "本地通知标题" content.body = message content.sound = .default let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil) UNUserNotificationCenter.current().add(request) } // 设置Messaging代理(可选,处理主题订阅的回调) Messaging.messaging().delegate = self return true }
2.2 处理用户点击通知的情况
实现userNotificationCenter(_:didReceive:withCompletionHandler:)方法,这个方法会在用户点击通知(无论App是否运行)时被调用:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo // 处理推送数据,比如跳转到指定页面 if let message = userInfo["message"] as? String { print("收到推送消息:\(message)") } completionHandler() }
3. 检查Xcode的Capabilities配置
这一步很容易忽略,必须确保:
- 打开
Push Notifications权限(Capabilities里直接搜索开启); - 打开
Background Modes,并勾选Remote notifications(这样App在后台/未运行时能接收静默推送)。
4. 测试注意事项
- 一定要用真机测试,iOS模拟器经常无法接收远程推送;
- 确保用户已经授权了推送权限(可以在App的设置里查看);
- 如果是测试主题推送,要确保设备已经成功订阅了主题(可以在
Messaging.messaging().subscribe(toTopic:)的回调里确认,或者用Firebase控制台的测试功能)。
内容的提问来源于stack exchange,提问作者mohamed ibrahem
相关产品推荐
相关产品推荐

