iOS低版本Firebase推送didReceiveRemoteNotification自动触发问题求助
解决iOS低版本Firebase推送自动触发didReceiveRemoteNotification的问题
嘿,这个问题我之前帮朋友排查过,结合Firebase推送在iOS低版本的特性,给你梳理下原因和解决方案:
为什么会出现这个情况?
核心差异在于iOS 10前后对推送回调的处理逻辑不一样:
- iOS 10+用
UNUserNotificationCenterDelegate来管理通知,能清晰区分前台接收、后台点击等场景; - 但iOS 10以下,
didReceiveRemoteNotification的触发逻辑更“宽泛”:如果你的推送Payload里带了content-available: 1(哪怕你没打算发静默通知),或者Firebase在低版本下默认给你加了这个字段,那么App在后台时,系统会自动唤醒App触发这个回调,根本不需要用户点击通知。 - 从你贴的通知内容看,虽然没直接看到
content-available,但Firebase的内部字段e=1(标识普通通知),不排除SDK在低版本下的兼容性问题,或者你推送配置里不小心开了静默相关的选项。
具体怎么解决?
1. 先检查推送Payload的结构
这是最关键的一步:
- 如果是通过Firebase Console发推送,别勾选“发送静默通知”那个选项;
- 如果是用API发,确保
aps字典里没有"content-available": 1(除非你真的需要静默唤醒功能)。
给你个正确的普通推送Payload示例:
{ "aps": { "alert": { "title": "title here", "body": "body text" }, "sound": "default" }, "from": "2343434" }
2. 在回调里加判断逻辑,过滤自动触发的情况
如果实在没法避免Payload里出现content-available(比如某些业务场景需要),可以在didReceiveRemoteNotification里加判断,只处理用户点击触发的情况:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { // 先解析aps字段 guard let aps = userInfo["aps"] as? [String: Any] else { completionHandler(.noData) return } // 区分是静默通知自动触发,还是用户点击触发 if let contentAvailable = aps["content-available"] as? Int, contentAvailable == 1 { // 这是系统自动唤醒的静默通知,不用处理业务逻辑 completionHandler(.noData) return } // 再判断App状态:只有当App从后台被唤醒(用户点击),或者前台接收时才处理 if application.applicationState == .active || application.applicationState == .inactive { // 这里写你的通知处理逻辑 handleNotification(userInfo: userInfo) } completionHandler(.noData) }
3. 结合Firebase的消息标识做判断
Firebase推送的userInfo里的e字段(你看到的e=1)是消息类型标识,e=1对应普通通知。你可以结合这个字段进一步过滤:
if let eventType = userInfo["e"] as? Int, eventType == 1 { // 只有用户点击通知唤醒App时才处理 if application.applicationState != .active { handleNotification(userInfo: userInfo) } }
4. 检查Firebase SDK版本
老版本的Firebase Messaging SDK可能在iOS低版本上有兼容性问题,建议升级到适配你最低iOS版本的最新稳定版,避免SDK层面的bug导致异常触发。
最后提醒下
测试一定要用真实设备,模拟器对推送的处理和真实设备差异很大;另外,iOS 10以下的系统,普通通知(不带content-available)只有用户点击才会触发didReceiveRemoteNotification,所以核心还是把Payload里的静默字段控制好。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

