Apple は、iOS 17 で重複を引き起こすバグを認めました。これは iOS 17.3 で修正されました。詳細はこちら。
OneSignal が重複配信を防止する仕組み
OneSignal は、配信がサーバーを離れる前に重複を排除します。すべての送信は 2 つのレベルでチェックされます:同じ通知が同じサブスクリプションに 2 回配信されることはなく、送信中にトークンが別のサブスクリプションに移動した場合でも、同じデバイストークンに 2 回配信されることはありません。冪等キーはこの保護を独自の API 再試行にも拡張し、モバイル SDK はすでに処理した通知をスキップします。 これらのチェックにより、デバイス上の重複は通常、送信パイプラインまたは通知を表示するアプリコードに起因します。以下のセクションで発生箇所を特定できます。まずここから
状況に最も合うセクションを選択してください:- 独自のバックエンドまたはパイプラインから API 経由でメッセージを送信している → 同じメッセージが複数回送信される
- アプリが OneSignal と並行して Firebase または別のプッシュ SDK を使用している → サードパーティ通知ハンドラー
- Android アプリがコードで通知をカスタマイズしている(サービス拡張機能またはフォアグラウンドリスナー)→ Android 通知ハンドラー
- iOS アプリが独自の
UNUserNotificationCenterDelegateを実装している → iOS フォアグラウンドハンドラー - 開発ビルドまたは複数のインストールでのみ重複が見られる → 複数のアプリインスタンス
- Android でアプリを開いたときに、以前配信された古い通知が再表示される → これらは復元された通知であり、重複ではありません。復元された通知を参照してください
同じメッセージが複数回送信される
重複通知の最も一般的な原因は、OneSignal API 経由で同じ通知ペイロードを複数回送信することです。一般的な理由:- サーバーが最初のリクエストが成功したかどうかを確認せずにリクエストを再試行します。
- バックエンドパイプラインのロジックが同じ通知を 2 回送信しています。
- OneSignal に移行中だが、以前のプロバイダーからまだ通知を送信している。両方のシステムから同時に送信しないでください。
冪等 API リクエスト
再試行時に冪等キーを再利用することで重複メッセージを防止します。
サードパーティ通知ハンドラー
アプリ内の他のコードが OneSignal のプッシュペイロードを処理し、OneSignal に加えて独自の通知を表示する場合に重複が発生します。これには以下が含まれます:- 同じペイロードを受信する他のリモートプッシュ SDK(例:Firebase Cloud Messaging)。
- Android の
FirebaseMessagingServiceや iOS のUNUserNotificationCenterDelegateなどのカスタムメッセージハンドラーが受信ペイロードを読み取り、ローカル通知を構築する場合。
OneSignal 通知の識別
すべての OneSignal 通知には、OneSignal 通知 UUID を含むi キーを持つ custom オブジェクトが含まれます:
JSON
サードパーティハンドラーから OneSignal 通知をフィルタリングする
OneSignal 以外のすべてのハンドラーで、custom.i キーを確認し、存在する場合は早期リターンします。OneSignal は自身のペイロードを処理し、他のコードは独自のペイロードの処理を続けます。
- Android
- iOS
カスタム
FirebaseMessagingService または他のリモートメッセージハンドラーで:Kotlin
Android 通知ハンドラー
OneSignal は、通知が表示される前に傍受してカスタマイズできる 2 つの Android コールバックを提供します:- 通知サービス拡張機能の
onNotificationReceived:アプリがバックグラウンドにある場合も含め、すべてのプッシュで実行され、復元された通知に対しても実行されます。 - フォアグラウンドライフサイクルリスナーの
onWillDisplay:アプリがフォアグラウンドにある場合のみ実行されます。
preventDefault() と display() のルール
OneSignal は、event.preventDefault() で抑制しない限り、各通知を自動的に表示します。2 つのよくある間違いが重複を引き起こします:
- 最初に
event.preventDefault()を呼び出さずにevent.getNotification().display()を呼び出すと、通知が 2 回表示されます。 - OneSignal がオリジナルを表示している間に
NotificationManagerCompat.notify()で別の通知を投稿する。
display() か、独自の NotificationManagerCompat.notify() のどちらか一方のみで、両方は使用しないでください。
onWillDisplay にも適用されます:
Kotlin
コールバック内の非同期処理
表示前にバックグラウンド処理(ネットワーク呼び出し、データベース検索)を行う場合は、コールバック内で同期的にpreventDefault() を呼び出し、非同期処理が完了した後にのみ display() を呼び出してください。preventDefault() なしでコールバックから戻ると OneSignal が通知を表示してしまい、その後に display() を呼び出すと重複が発生します。
非同期処理は 30 秒以内に完了させてください。それを過ぎると SDK はコールバックの待機を停止し、preventDefault() で保留された通知は表示されずに破棄されます。
iOS フォアグラウンドハンドラー
OneSignal は、SDK の初期化時に自身をUNUserNotificationCenterDelegate として設定します。アプリがフォアグラウンド通知処理も実装している場合、通知が 2 回表示される可能性があります——OneSignal からの 1 回とコードからの 1 回です。
重複を引き起こす一般的なパターン:
- OneSignal への呼び出しを転送せずに独自の
UNUserNotificationCenterDelegateを実装し、同じメソッドからcompletionHandler([.banner, .sound])を呼び出してカスタムアプリ内アラートを表示する。 - OneSignal も表示している受信プッシュに応答してローカル通知(
UNUserNotificationCenter.current().add(...))をスケジュールする。
event.preventDefault() を呼び出してください:
Swift
複数のアプリインスタンス
- Android
- iOS
- Web
アプリの本番バージョンと開発バージョンの両方がインストールされている場合、重複が発生する可能性があります。各アプリには一意のパッケージ名があり、独自のプッシュトークンを受け取ります。通知を長押しして、どのアプリインスタンスから送信されたかを確認します。
診断のヒント
重複問題のデバッグを迅速に行うために、次の情報を収集して OneSignal サポートに送信してください:- 重複を受け取ったデバイスの OneSignal サブスクリプション ID
- OneSignal メッセージ ID またはダッシュボード内のメッセージへのリンク
- アプリ内の他のライブラリまたはプラグインのリスト
- 問題を再現するデバッグログ
- 詳細な再現手順
FAQ
アプリに 2 つの通知 SDK がある場合はどうなりますか?
両方の SDK が同じ通知を独立して処理・表示する可能性があります。OneSignal は自身の通知を自動的にフィルタリングしますが、他の SDK はフィルタリングしません。custom.i キーを確認することで、他の SDK のハンドラーから OneSignal ペイロードをフィルタリングしてください。コード例については、サードパーティ通知ハンドラーを参照してください。
以前のプロバイダーと OneSignal から同時にプッシュを送信するには?
段階的に移行できますが、両方のプロバイダーから同じメッセージを送信しないようにしてください。- Android:OneSignal を統合してアプリをリリースする際に、古い SDK の通知処理コードを削除します。ユーザーが更新すると、古いプロバイダーからのプッシュを受信しなくなります。
- iOS:ユーザーが更新している間、一時的に古いプロバイダーから送信を続けることができます。完全に移行したら、重複を避けるために OneSignal からのみ送信してください。
OneSignal にはオーディエンスへの重複送信を防ぐ仕組みがありますか?
はい。配信は OneSignal のサーバーを離れる前に、通知ごと・サブスクリプションごと、および通知ごと・デバイストークンごとの 2 つのレベルで重複排除されます。独自の API 再試行は冪等キーによって保護されます。OneSignal が重複配信を防止する仕組みを参照してください。急速に変化する更新に対して複数の通知を防ぐには?
通知作成 API でcollapse_id を使用して、通知を積み重ねる代わりに以前の通知を置き換えます。複数の通知が同じ collapse_id を共有する場合、各新しい通知はトレイ内の前の通知を置き換えます。これは株価更新、ライブスコア、配送の到着予定時刻、および同様の頻繁な更新に役立ちます。
関連ページ
モバイル SDK トラブルシューティング
iOS および Android でのプッシュ通知配信に関する一般的な問題を解決します。
Web プッシュトラブルシューティング
Web プッシュのサブスクリプション、Service Worker、配信の問題をデバッグします。
アプリ内メッセージトラブルシューティング
アプリ内メッセージの表示、トリガー、重複に関する問題を修正します。
モバイルサービス拡張機能
iOS および Android で表示前にプッシュ通知を傍受してカスタマイズします。
通知が表示されない(Web)
送信されたが表示されない Web プッシュ通知のトラブルシューティング。
通知トレイの管理
モバイル通知のクリック、却下、復元、クリアの動作。