Apple 确认了 iOS 17 中导致重复的错误。此问题已在 iOS 17.3 中修复。了解更多。
从这里开始
选择最符合您情况的部分:- 您的服务器重试失败的 API 调用,或后端管道可能重复发送 → 多次发送相同消息
- 您的应用与 OneSignal 一起使用 Firebase 或其他推送 SDK → 第三方通知处理程序
- 您的 Android 应用在代码中自定义通知(服务扩展或前台监听器)→ Android 通知处理程序
- 您的 iOS 应用实现了自己的
UNUserNotificationCenterDelegate→ iOS 前台处理程序 - 您只在开发构建或多次安装时看到重复 → 多个应用实例
多次发送相同消息
重复通知的最常见原因是通过 OneSignal API 多次发送相同的通知载荷。常见原因:- 您的服务器重试请求而不检查第一次是否成功。
- 后端管道中的逻辑重复发送了同一通知。
- 您正在迁移到 OneSignal 但仍从之前的提供商发送通知。避免同时从两个系统发送。
幂等 API 请求
通过在重试时复用幂等键来防止重复消息。
第三方通知处理程序
当应用中的其他代码处理 OneSignal 的推送载荷并在 OneSignal 之外额外显示通知时,就会出现重复。包括:- 其他接收相同载荷的远程推送 SDK(例如 Firebase Cloud Messaging)。
- 自定义消息处理程序,例如 Android 上的
FirebaseMessagingService或 iOS 上的UNUserNotificationCenterDelegate,它们读取传入载荷并从中构建本地通知。
识别 OneSignal 通知
每条 OneSignal 通知都包含一个带有i 键的 custom 对象,其中包含 OneSignal 通知 UUID:
JSON
从第三方处理程序中过滤 OneSignal 通知
在任何非 OneSignal 的处理程序中,检查custom.i 键,并在其存在时提前返回。OneSignal 随后处理自己的载荷,而您的其他代码继续处理自己的载荷。
- Android
- iOS
在自定义
FirebaseMessagingService 或其他远程消息处理程序中:Kotlin
Android 通知处理程序
OneSignal 提供了两个 Android 回调,允许您在通知显示之前拦截和自定义: 当这些回调除了 OneSignal 的自动显示之外还显示通知时,就会出现重复。preventDefault() 和 display() 规则
OneSignal 会自动显示每条通知,除非您通过 event.preventDefault() 抑制它。两个常见错误会导致重复:
- 在未首先调用
event.preventDefault()的情况下调用event.getNotification().display()——会导致通知显示两次。 - 在 OneSignal 也显示原始通知时,使用
NotificationManagerCompat.notify()另外发布一条通知。
display(),要么是您自己的 NotificationManagerCompat.notify(),不能同时使用两者。
onWillDisplay:
Kotlin
回调中的异步工作
当您在显示之前执行后台工作(网络调用、数据库查找)时,请在回调中同步调用preventDefault(),并仅在异步工作完成后调用 display()。在不调用 preventDefault() 的情况下从回调返回会让 OneSignal 显示通知,之后再调用 display() 则会产生重复。
iOS 前台处理程序
OneSignal 在 SDK 初始化期间将自身设置为UNUserNotificationCenterDelegate。如果您的应用也实现了前台通知处理,通知可能会显示两次——一次来自 OneSignal,一次来自您的代码。
导致重复的常见模式:
- 实现了自己的
UNUserNotificationCenterDelegate而不将调用转发给 OneSignal,然后在同一方法中调用completionHandler([.banner, .sound])并显示自定义的应用内警报。 - 在 OneSignal 也在显示传入推送的同时调度本地通知(
UNUserNotificationCenter.current().add(...))。
event.preventDefault():
Swift
多个应用实例
- Android
- iOS
- Web
当您同时安装了应用的生产版本和开发版本时,可能会出现重复。每个应用都有唯一的包名并接收自己的推送令牌。长按通知以确认是哪个应用实例发送的。
诊断提示
为了更快地调试重复问题,请收集以下信息并发送给 OneSignal 支持:- 收到重复通知的设备的 OneSignal 订阅 ID
- OneSignal 消息 ID 或仪表板中消息的链接
- 应用中其他库或插件的列表
- 重现问题的调试日志
- 详细的复现步骤
常见问题
如果我的应用中有两个通知 SDK 会怎样?
两个 SDK 可能会独立处理并显示同一通知。OneSignal 会自动过滤自己的通知,但其他 SDK 不会。通过检查custom.i 键,从其他 SDK 的处理程序中过滤 OneSignal 载荷。有关代码示例,请参阅第三方通知处理程序。
如何同时从之前的提供商和 OneSignal 发送推送?
您可以逐步过渡,但要避免从两个提供商发送相同的消息。- Android:在集成 OneSignal 并发布应用时删除旧 SDK 通知处理代码。随着用户更新,他们将停止接收来自旧提供商的推送。
- iOS:在用户更新期间,您可以暂时继续从旧提供商发送。完全过渡后,仅从 OneSignal 发送以避免重复。
如何防止快速变化更新的多条通知?
在创建通知 API 中使用collapse_id 来替换之前的通知而不是堆叠它们。当多条通知共享相同的 collapse_id 时,每条新通知都会替换通知栏中的上一条。这对于股票价格更新、实时比分、配送预计到达时间和类似的频繁更新非常有用。
相关页面
移动 SDK 故障排除
解决 iOS 和 Android 上推送通知投递的常见问题。
Web 推送故障排除
调试 Web 推送订阅、Service Worker 和投递问题。
应用内消息故障排除
修复应用内消息显示、触发器和重复问题。
移动服务扩展
在 iOS 和 Android 上显示之前拦截和自定义推送通知。
未显示的通知(Web)
对已发送但未显示的 Web 推送通知进行故障排除。