Swift iOS应用集成FCM与Pushy后重复通知的后台处理咨询
iOS 双推送服务(FCM+Pushy)后台重复通知处理方案
前端可行处理方案
你当前后台代码用计数删除通知的逻辑完全不可靠——推送送达顺序不固定,也没法关联两条重复通知的唯一标识。要解决这个问题,核心是利用你已经用到的notification_id字段,精准定位并删除重复项。
修正后的代码实现
首先确保FCM和Pushy的服务端推送时,userInfo里都携带同一个全局唯一的notification_id。然后修改后台回调逻辑:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { // 先处理两个推送SDK的原生逻辑 Pushy.shared?.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: { _ in }) // 如果用Firebase Messaging,也要调用对应的处理方法: // Messaging.messaging().appDidReceiveMessage(userInfo) // 提取当前推送的唯一标识 guard let currentNotifID = userInfo["notification_id"] as? String else { completionHandler(.noData) return } let center = UNUserNotificationCenter.current() center.getDeliveredNotifications { deliveredNotifications in // 筛选出所有已送达且和当前推送ID重复的通知 let duplicateIDs = deliveredNotifications.compactMap { notif in guard let notifID = notif.request.content.userInfo["notification_id"] as? String, notifID == currentNotifID else { return nil } return notif.request.identifier } // 删除重复通知 if !duplicateIDs.isEmpty { center.removeDeliveredNotifications(withIdentifiers: duplicateIDs) } completionHandler(.newData) } }
前端处理的局限性
需要注意:应用后台时,普通远程推送是先由APNs直接展示通知,再触发didReceiveRemoteNotification回调。所以用这种方法删除重复通知,可能会出现两条通知短暂同时显示的情况(视觉闪一下),这是客户端处理无法避免的问题。
更推荐的服务端修改方案(Apple官方最佳实践)
Apple在远程推送文档中明确要求:推送服务端必须保证推送的唯一性,避免重复发送相同内容的通知,原因包括:
- 客户端无法完全控制推送的送达顺序和回调时机,去重逻辑可能失效。
- 普通推送由APNs直接展示,客户端只能在展示后删除重复项,无法拦截展示过程,用户会看到短暂的重复通知。
- 重复推送会浪费APNs资源和客户端处理性能,不符合Apple的性能优化规范。
正确的服务端做法是:针对同一条通知内容,只选择FCM或Pushy其中一个通道发送;或者在发送前校验notification_id,避免重复触发推送。
内容的提问来源于stack exchange,提问作者Swifty Man
相关产品推荐
相关产品推荐

