> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Notificações Duplicadas

> Solucione notificações push duplicadas causadas por conflitos de SDK, novas tentativas do lado do servidor, ambientes multi-app e bugs específicos de plataforma.

Notificações duplicadas ocorrem quando o mesmo dispositivo recebe o mesmo conteúdo de mensagem mais de uma vez. Este guia aborda as causas mais comuns e como resolvê-las.

Se o mesmo usuário ver a notificação em múltiplos dispositivos (telefone, tablet, desktop), esse é o comportamento esperado com base na sua configuração de segmentação (segmentos, IDs externos, etc.). Para mensagens in-app duplicadas, consulte o guia de [solução de problemas de mensagens in-app](./in-app-message-troubleshooting#duplicated-in-app-messages).

<Info>
  A Apple reconheceu um bug no iOS 17 que causava duplicatas. Isso foi corrigido no iOS 17.3. [Leia mais](https://forums.developer.apple.com/forums/thread/747044).
</Info>

## Comece aqui

Escolha a seção que melhor corresponde à sua situação:

* Seu servidor tenta novamente chamadas de API com falha ou seu pipeline de backend pode enviar em duplicata → [Mesma mensagem enviada múltiplas vezes](#mesma-mensagem-enviada-múltiplas-vezes)
* Seu app usa Firebase ou outro SDK de push junto com OneSignal → [Manipuladores de notificação de terceiros](#manipuladores-de-notificação-de-terceiros)
* Seu app Android personaliza notificações no código (extensão de serviço ou listener em primeiro plano) → [Manipuladores de notificação Android](#manipuladores-de-notificação-android)
* Seu app iOS implementa seu próprio `UNUserNotificationCenterDelegate` → [Manipulador em primeiro plano do iOS](#manipulador-em-primeiro-plano-do-ios)
* Você só vê duplicatas em builds de desenvolvimento ou com múltiplas instalações → [Múltiplas instâncias de app](#múltiplas-instâncias-de-app)

## Mesma mensagem enviada múltiplas vezes

A causa mais comum é enviar o mesmo payload de notificação mais de uma vez através da API do OneSignal. Razões comuns:

* Seu servidor tenta novamente as requisições sem verificar se a primeira foi bem-sucedida.
* Lógica duplicada no seu pipeline de backend envia a mesma notificação duas vezes.
* Você está migrando para o OneSignal mas ainda está enviando notificações de um provedor anterior. Evite enviar de ambos os sistemas ao mesmo tempo.

<Card title="Requisições de API idempotentes" icon="rotate" href="/reference/idempotent-notification-requests">
  Evite mensagens duplicadas reutilizando chaves de idempotência em novas tentativas.
</Card>

## Manipuladores de notificação de terceiros

Duplicatas podem ocorrer quando outro código no seu app processa o payload push do OneSignal e exibe sua própria notificação além da do OneSignal. Isso inclui:

* Outros SDKs de push remoto (por exemplo, Firebase Cloud Messaging) que recebem o mesmo payload.
* Manipuladores de mensagens personalizados como um `FirebaseMessagingService` no Android ou um `UNUserNotificationCenterDelegate` no iOS que leem o payload de entrada e constroem uma notificação local a partir dele.

O SDK do OneSignal filtra automaticamente os payloads do OneSignal quando é o único manipulador. O código de terceiros não sabe filtrá-los a menos que você o instrua.

### Identificando notificações do OneSignal

Cada notificação do OneSignal inclui um objeto `custom` com uma chave `i` contendo o UUID da notificação do OneSignal:

```json JSON theme={null}
{
  "custom": {
    "i": "the-notification-id"
  }
}
```

Para a referência completa do payload, consulte [Estrutura de payload personalizado do OneSignal](./osnotification-payload#custom-onesignal-payload-structure).

### Filtrando notificações do OneSignal em manipuladores de terceiros

Em qualquer manipulador não-OneSignal, verifique a chave `custom.i` e retorne antecipadamente quando ela estiver presente. O OneSignal então lida com seus próprios payloads enquanto seu outro código continua processando os seus.

<Tabs>
  <Tab title="Android">
    Em um `FirebaseMessagingService` personalizado ou outro manipulador de mensagens remotas:

    ```kotlin Kotlin theme={null}
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        val customJson = remoteMessage.data["custom"]
        if (customJson != null) {
            try {
                val custom = JSONObject(customJson)
                if (custom.has("i")) {
                    // Notificação do OneSignal — deixar o SDK do OneSignal lidar com ela
                    return
                }
            } catch (e: JSONException) {
                // Não é um payload do OneSignal, continuar
            }
        }

        // Lidar com sua própria notificação aqui
    }
    ```
  </Tab>

  <Tab title="iOS">
    No seu `UNUserNotificationCenterDelegate` ou um manipulador de notificações personalizado:

    ```swift Swift theme={null}
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        let userInfo = notification.request.content.userInfo

        if let custom = userInfo["custom"] as? [String: Any], custom["i"] != nil {
            // Notificação do OneSignal — deixar o SDK do OneSignal lidar com ela
            completionHandler([])
            return
        }

        // Lidar com sua própria notificação aqui
    }
    ```
  </Tab>
</Tabs>

<Tip>
  Se você controla a estrutura do payload enviado pelo seu outro provedor, adicione uma chave marcadora distinta (por exemplo, `my_app_notification: true`) e filtre em ambas as direções — lide apenas com notificações contendo seu marcador no seu próprio código, e deixe o OneSignal lidar com notificações contendo a chave `custom.i`.
</Tip>

## Manipuladores de notificação Android

O OneSignal expõe dois callbacks Android que permitem interceptar e personalizar uma notificação antes de ser exibida:

* `onNotificationReceived` em uma [extensão de serviço de notificação](./service-extensions) — executado para cada push, inclusive quando o app está em segundo plano.
* `onWillDisplay` em um [listener de ciclo de vida em primeiro plano](./mobile-sdk-reference#addforegroundlifecyclelistener-push) — executado apenas quando o app está em primeiro plano.

Duplicatas ocorrem quando esses callbacks exibem a notificação além da exibição automática do OneSignal.

### A regra de `preventDefault()` e `display()`

O OneSignal exibe cada notificação automaticamente a menos que você a suprima com `event.preventDefault()`. Dois erros comuns causam duplicatas:

* Chamar `event.getNotification().display()` sem primeiro chamar `event.preventDefault()` — exibe a notificação duas vezes.
* Postar uma notificação separada com [`NotificationManagerCompat.notify()`](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat) enquanto o OneSignal também exibe a original.

Apenas um caminho de exibição deve estar ativo — o `display()` do OneSignal ou o seu próprio `NotificationManagerCompat.notify()`, nunca ambos.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  override fun onNotificationReceived(event: INotificationReceivedEvent) {
      event.preventDefault()

      val notification = event.notification
      notification.setExtender { builder ->
          builder.setColor(0xFF0000FF.toInt())
      }
      notification.display()
  }
  ```

  ```java Java theme={null}
  @Override
  public void onNotificationReceived(INotificationReceivedEvent event) {
      event.preventDefault();

      IDisplayableMutableNotification notification = event.getNotification();
      notification.setExtender(builder ->
          builder.setColor(0xFF0000FF)
      );
      notification.display();
  }
  ```
</CodeGroup>

A mesma regra se aplica dentro de `onWillDisplay` em um listener de ciclo de vida em primeiro plano:

```kotlin Kotlin theme={null}
OneSignal.Notifications.addForegroundLifecycleListener(object : INotificationLifecycleListener {
    override fun onWillDisplay(event: INotificationWillDisplayEvent) {
        event.preventDefault()

        // Renderize sua própria UI ou chame event.notification.display() para exibir a notificação do OneSignal
    }
})
```

<Warning>
  Se você chamar `preventDefault()` mas nunca chamar `display()`, a notificação será silenciosamente descartada e o usuário não a verá. Cada caminho de código deve chamar `display()` uma vez ou suprimir intencionalmente a notificação.
</Warning>

<Warning>
  Se você usar tanto uma extensão de serviço de notificação quanto um listener de ciclo de vida em primeiro plano, certifique-se de que apenas um manipulador exibe a notificação para um determinado estado do app. Chamar `display()` de ambos produz duplicatas.
</Warning>

### Trabalho assíncrono dentro de callbacks

Quando você faz trabalho em segundo plano (chamadas de rede, consultas ao banco de dados) antes de exibir, chame `preventDefault()` de forma síncrona no callback e chame `display()` apenas após o trabalho assíncrono ser concluído. Retornar do callback sem `preventDefault()` permite que o OneSignal exiba a notificação, e uma chamada posterior a `display()` produz uma duplicata.

## Manipulador em primeiro plano do iOS

O OneSignal se define como o `UNUserNotificationCenterDelegate` durante a inicialização do SDK. Se seu app também implementa o tratamento de notificações em primeiro plano, a notificação pode ser exibida duas vezes — uma vez pelo OneSignal e uma vez pelo seu código.

Padrões comuns que causam duplicatas:

* Implementar seu próprio `UNUserNotificationCenterDelegate` sem encaminhar chamadas para o OneSignal, depois chamar `completionHandler([.banner, .sound])` e exibir um alerta in-app personalizado do mesmo método.
* Agendar uma notificação local (`UNUserNotificationCenter.current().add(...)`) em resposta a um push de entrada que o OneSignal também está exibindo.

Para controlar a exibição em primeiro plano sem causar duplicatas, use o [listener de ciclo de vida em primeiro plano](./mobile-sdk-reference#addforegroundlifecyclelistener-push) do OneSignal e chame `event.preventDefault()` quando quiser renderizar a notificação você mesmo:

```swift Swift theme={null}
OneSignal.Notifications.addForegroundLifecycleListener(self)

func onWillDisplay(event: OSNotificationWillDisplayEvent) {
    event.preventDefault()

    // Renderize sua própria UI ou chame event.notification.display() para exibir a notificação do OneSignal
}
```

## Múltiplas instâncias de app

<Tabs>
  <Tab title="Android">
    Duplicatas podem ocorrer quando você tem versões de produção e desenvolvimento do seu app instaladas. Cada app tem um nome de pacote único e recebe seu próprio token push.

    Pressione e segure a notificação para confirmar qual instância do app a enviou.
  </Tab>

  <Tab title="iOS">
    Se dois registros de dispositivo no OneSignal compartilham o mesmo token push, o dispositivo pode receber duas notificações. Isso pode acontecer quando o mesmo token é importado ou registrado várias vezes. O OneSignal inclui verificações para prevenir isso, mas casos extremos podem contorná-las.
  </Tab>

  <Tab title="Web">
    Duplicatas de web push são causadas por inscrever-se em múltiplas origens usando o mesmo OneSignal App ID. Uma [origem](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) é a combinação de esquema, host e porta que o navegador usa para delimitar assinaturas push.

    Por exemplo, um usuário que se inscreve em `https://example.com` e `https://sub.example.com` conta como duas assinaturas, e um envio usando o mesmo App ID atinge ambas.

    Para corrigir:

    1. [Redefinir dados do navegador e permissões push](./troubleshooting-web-push) por origem.
    2. Se muitos usuários forem afetados, crie um novo App OneSignal e use o novo App ID no código init do seu site.
    3. Peça aos usuários para revisitar o site e se reinscrever.

    Inscrever-se em múltiplos navegadores ou perfis de navegador também leva a múltiplas notificações.
  </Tab>
</Tabs>

## Dicas de diagnóstico

Para depurar duplicatas mais rapidamente, colete e envie o seguinte ao suporte do OneSignal:

* ID de assinatura do OneSignal do dispositivo que recebeu as duplicatas
* ID da mensagem do OneSignal ou um link para a mensagem no painel
* Lista de outras bibliotecas ou plugins no seu app
* [Log de depuração reproduzindo o problema](./capturing-a-debug-log)
* Etapas detalhadas de reprodução

## FAQ

### O que acontece se eu tiver dois SDKs de notificação no meu app?

Ambos os SDKs podem processar e exibir independentemente a mesma notificação. O OneSignal filtra suas próprias notificações automaticamente, mas outros SDKs não fazem isso. Filtre os payloads do OneSignal dos manipuladores do seu outro SDK verificando a chave `custom.i`. Consulte [Manipuladores de notificação de terceiros](#manipuladores-de-notificação-de-terceiros) para exemplos de código.

### Como enviar push de um provedor anterior e OneSignal ao mesmo tempo?

Você pode fazer a transição gradualmente, mas evite enviar a mesma mensagem de ambos os provedores.

* **Android**: Remova o código de manipulação de notificação do SDK antigo ao integrar o OneSignal e lançar o app. À medida que os usuários atualizam, eles param de receber push do provedor antigo.
* **iOS**: Você pode continuar enviando do provedor antigo temporariamente enquanto os usuários atualizam. Uma vez totalmente transicionado, envie apenas do OneSignal para evitar duplicatas.

### Como evitar múltiplas notificações para atualizações que mudam rapidamente?

Use um [`collapse_id`](/reference/push-notification#body-parameters) na API [Criar notificação](/reference/push-notification) para substituir notificações anteriores em vez de empilhá-las. Quando múltiplas notificações compartilham o mesmo `collapse_id`, cada nova substitui a notificação anterior na bandeja. Isso é útil para atualizações de preços de ações, placares ao vivo, ETAs de entrega e atualizações frequentes similares.

## Páginas relacionadas

<Columns cols={2}>
  <Card title="Solução de problemas do SDK móvel" icon="mobile" href="./mobile-troubleshooting">
    Resolva problemas comuns com a entrega de notificações push no iOS e Android.
  </Card>

  <Card title="Solução de problemas de web push" icon="browser" href="./troubleshooting-web-push">
    Depure problemas de assinatura, service worker e entrega de web push.
  </Card>

  <Card title="Solução de problemas de mensagens in-app" icon="message" href="./in-app-message-troubleshooting">
    Corrija problemas com exibição, gatilhos e duplicatas de mensagens in-app.
  </Card>

  <Card title="Extensões de serviço móvel" icon="gear" href="./service-extensions">
    Intercepte e personalize notificações push antes da exibição no iOS e Android.
  </Card>

  <Card title="Notificações não exibidas (web)" icon="bell-slash" href="./notifications-not-shown-web-push">
    Solucione notificações web push que são enviadas mas não exibidas.
  </Card>
</Columns>
