Pular para o conteúdo principal
As Extensões de Serviço de Notificação permitem que você intercepte e modifique notificações push antes de serem exibidas ao usuário. Isso habilita o manuseio de dados em segundo plano, estilos personalizados, anexos de rich media, entrega confirmada e opções de botões de ação.
Você pode acessar os dados em suas notificações push enviadas do OneSignal através da classe OSNotification

Extensão de Serviço de Notificação do Android

Permite que você processe a notificação antes de ser mostrada ao usuário. Casos de uso comuns incluem:
  • Receber dados em segundo plano com ou sem exibir uma notificação.
  • Substituir configurações específicas de notificação dependendo da lógica do aplicativo do lado do cliente, como cor de destaque personalizada, padrão de vibração ou qualquer outra opção NotificationCompat disponível.
Para mais detalhes, consulte a documentação do Android sobre as opções do NotificationCompat.

Passo 1: Criar uma classe para a extensão de serviço

Crie uma classe que implementa INotificationServiceExtension e implemente o método onNotificationReceived. O parâmetro do método onNotificationReceived é event do tipo INotificationReceivedEvent.
package your.package.name

import androidx.annotation.Keep;
import com.onesignal.notifications.IActionButton;
import com.onesignal.notifications.IDisplayableMutableNotification;
import com.onesignal.notifications.INotificationReceivedEvent;
import com.onesignal.notifications.INotificationServiceExtension;

@Keep // Keep is required to prevent minification from renaming or removing your class
public class NotificationServiceExtension implements INotificationServiceExtension {

     @Override
     public void onNotificationReceived(INotificationReceivedEvent event) {
        IDisplayableMutableNotification notification = event.getNotification();

        if (notification.getActionButtons() != null) {
           for (IActionButton button : notification.getActionButtons()) {
              // you can modify your action buttons here
           }
        }

     /* Add customizations here. See examples below for additional methods to modify the notification*/
     }
}

A anotação @Keep é necessária para evitar que o ProGuard ou o R8 renomeie ou remova sua classe durante a minificação.

Passo 2: Personalizar a notificação

Os exemplos a seguir mostram personalizações comuns que você pode implementar na classe de Extensão de Serviço de Notificação.
Use event.preventDefault() para suprimir a exibição da notificação. Em seguida, você pode chamar event.getNotification().display() para exibi-la mais tarde, ou nunca chamá-la para descartá-la silenciosamente.
event.preventDefault();

//Do some async work, then decide to show or dismiss
new Thread(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException ignored) {}

    //Manually show the notification
    event.getNotification().display();
}).start();
Chamar event.preventDefault() sem nunca chamar display() descartará a notificação silenciosamente. Se a intenção for suprimir permanentemente, isso é esperado. Para mais informações, consulte Notificações duplicadas.

Passo 3: Adicionar a extensão de serviço ao seu AndroidManifest.xml

Adicione o nome da classe e o valor como meta-data dentro do arquivo AndroidManifest.xml na tag do aplicativo. Ignore quaisquer avisos de “não utilizado”.
XML
<application>
  <meta-data
    android:name="com.onesignal.NotificationServiceExtension"
    android:value="com.onesignal.example.NotificationServiceExtension" />
</application>
Substitua com.onesignal.example.NotificationServiceExtension pelo nome totalmente qualificado da sua classe.

Extensão de Serviço de Notificação do iOS

A UNNotificationServiceExtension permite que você modifique o conteúdo das notificações push antes de serem exibidas ao usuário e é necessária para outros recursos importantes como: Você provavelmente já configurou isso se seguiu nossas instruções de configuração do SDK Móvel para seu aplicativo, mas esta seção explicará como acessar os dados de payload de notificação do OneSignal e solucionar quaisquer problemas que você possa estar tendo.

Obtendo o payload de push do iOS

O override didReceive(_:withContentHandler:) chama OneSignalExtension.didReceiveNotificationExtensionRequest, que passa o bestAttemptContent para o OneSignal antes de ser exibido ao usuário. Você pode ler ou modificar bestAttemptContent antes que esse método seja chamado. Neste exemplo, enviamos uma notificação com os seguintes dados:
JSON
{
  "app_id": "YOUR_APP_ID",
  "target_channel": "push",
  "headings": {"en": "The message title"},
  "contents": {"en": "The message contents"},
  "data":{
    "additional_data_key_1":"value_1",
    "additional_data_key_2":"value_2"
    },
  "include_subscription_ids": ["SUBSCRIPTION_ID_1"]
}
Acesse estes data adicionais dentro da OneSignalNotificationServiceExtension através da chave a dentro do dicionário custom de userInfo:
if let bestAttemptContent = bestAttemptContent {

    if let customData = bestAttemptContent.userInfo["custom"] as? [String: Any],
       let additionalData = customData["a"] as? [String: Any] {

        if let jsonData = try? JSONSerialization.data(withJSONObject: additionalData, options: .prettyPrinted),
           let jsonString = String(data: jsonData, encoding: .utf8) {
            print("The additionalData dictionary in JSON format:\n\(jsonString)")
        } else {
            print("Failed to convert additionalData to JSON format.")
        }
    }

    if let messageData = bestAttemptContent.userInfo["aps"] as? [String: Any],
       let apsData = messageData["alert"] as? [String: Any],
       let body = apsData["body"] as? String,
       let title = apsData["title"] as? String {
        print("The message contents is: \(body), message headings is: \(title)")
    } else {
        print("Unable to retrieve apsData")
    }

    OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest,
                                                              with: bestAttemptContent,
                                                              withContentHandler: self.contentHandler)
}
Exemplo de saída do console:
The additionalData dictionary in JSON format:
{
  "additional_data_key_1" : "value_1",
  "additional_data_key_2" : "value_2"
}
The message contents is: The message contents, message headings is: The message title

Solução de problemas da Extensão de Serviço de Notificação do iOS

Este guia é para depurar problemas com Imagens, Botões de Ação ou Entregas Confirmadas que não aparecem em aplicativos móveis iOS.

Verifique suas Configurações do Xcode

Em General > Targets, certifique-se de que seu main app target e o target OneSignalNotificationServiceExtension tenham os mesmos e corretos:
  • Supported Destinations
  • Minimum Deployment (iOS 14.5 ou superior)
Se você estiver usando Cocoapods, certifique-se de que eles correspondam ao seu target principal no Podfile para evitar erros de compilação.
Xcode General tab showing Supported Destinations and Minimum Deployment for the main app target
Xcode General tab showing Supported Destinations and Minimum Deployment for the notification service extension target
Continuando na aba OneSignalNotificationServiceExtension > Info, expanda a chave NSExtension. Certifique-se de ver:
XML
 <dict>
   <key>NSExtensionPointIdentifier</key>
   <string>com.apple.usernotifications.service</string>
   <key>NSExtensionPrincipalClass</key>
   <string>$(PRODUCT_MODULE_NAME).NotificationService</string>
 </dict>
Exemplo:
Xcode Info tab showing the NSExtension dictionary with NSExtensionPointIdentifier and NSExtensionPrincipalClass keys
Se estiver usando Objective-C, em vez de $(PRODUCT_MODULE_NAME).NotificationService use NotificationService.

Desative “Copy only when installing”

Selecione seu main app target > Build Phases > Embed App Extensions. Certifique-se de que “Copy only when installing” NÃO esteja marcado. Desmarque-o se estiver:
Xcode Build Phases tab showing Embed App Extensions with Copy only when installing unchecked

Depurando a Extensão de Serviço de Notificação do iOS

Siga estas etapas para verificar se a Extensão de Serviço de Notificação está configurada corretamente.

1. Atualizar o código OneSignalNotificationServiceExtension

Abra NotificationService.m ou NotificationService.swift e substitua todo o conteúdo do arquivo pelo código abaixo. Isso adiciona logs para ajudar a verificar se a extensão está sendo executada. Substitua YOUR_BUNDLE_ID pelo seu Bundle ID real.
import UserNotifications
import OneSignalExtension
import os.log

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var receivedRequest: UNNotificationRequest!
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.receivedRequest = request
        self.contentHandler = contentHandler
        self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        let userInfo = request.content.userInfo
        let custom = userInfo["custom"]
        print("Running NotificationServiceExtension: userInfo = \(userInfo.description)")
        print("Running NotificationServiceExtension: custom = \(custom.debugDescription)")
        os_log("%{public}@", log: OSLog(subsystem: "YOUR_BUNDLE_ID", category: "OneSignalNotificationServiceExtension"), type: OSLogType.debug, userInfo.debugDescription)

        if let bestAttemptContent = bestAttemptContent {
            print("Running NotificationServiceExtension")
            bestAttemptContent.body = "[Modified] " + bestAttemptContent.body

            OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            OneSignalExtension.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }

}

Os tipos de log de depuração precisam ser habilitados no Console via Action > Include Debug Messages.

2. Alterar seu Active Scheme

Defina seu Active Scheme para OneSignalNotificationServiceExtension.
Xcode toolbar showing the active scheme dropdown set to OneSignalNotificationServiceExtension

3. Compilar e executar o projeto

Compile e execute o projeto no Xcode em um dispositivo real.

4. Abrir o Console

No Xcode, selecione Window > Devices and Simulators.
Xcode menu showing the Window dropdown with Devices and Simulators selected
Você deve ver seu dispositivo conectado. Selecione Open Console.
Xcode Devices window showing the Open Console button for a connected device

5. Verificar o Console

No Console:
  1. Selecione Action > Include Debug Messages
  2. Procure por OneSignalNotificationServiceExtension como a CATEGORY
  3. Selecione Start
macOS Console app showing the category filter and Start button for debugging the notification service extension
Envie para este dispositivo uma notificação com uma mensagem (use a propriedade contents se estiver enviando pela API Criar notificação). Neste exemplo, o payload é:
cURL
curl --request POST \
 --url 'https://api.onesignal.com/notifications' \
 --header 'Authorization: Key YOUR_API_KEY' \
 --header 'accept: application/json' \
 --header 'content-type: application/json' \
 --data '
{
"app_id": "YOUR_APP_ID",
"target_channel": "push",
"headings": {"en": "The message title"},
"contents": {"en": "The message contents"},
"data":{"additional_data_key_1":"value_1","additional_data_key_2":"value_2"},
"include_subscription_ids": [
"SUBSCRIPTION_ID_1"
]
}'
Você deve ver uma mensagem registrada com o aplicativo em execução e sem execução.
macOS Console app showing debug log output from the OneSignalNotificationServiceExtension
Se você não vir uma mensagem, remova o OneSignal do seu aplicativo e siga a Configuração do SDK Móvel novamente para verificar a integração.

FAQ

Por que minha extensão de serviço de notificação não está sendo executada no iOS? A extensão só é executada quando mutable-content está definido no payload da notificação. O OneSignal define isso automaticamente para notificações com anexos ou botões de ação. Verifique se as configurações do Xcode correspondem ao guia de solução de problemas. Posso impedir que uma notificação seja exibida no Android? Sim. Chame event.preventDefault() para suprimir a exibição. Em seguida, chame event.getNotification().display() para exibi-la mais tarde, ou nunca chame para descartá-la silenciosamente. Consulte Notificações duplicadas para mais informações. Preciso da anotação @Keep no Android? Sim. Ela evita que o ProGuard ou o R8 renomeie ou remova sua classe que implementa INotificationServiceExtension durante a minificação.

Páginas relacionadas

Configuração do SDK Móvel

Instale e configure o SDK do OneSignal para iOS e Android.

Imagens e rich media

Anexe imagens, GIFs e vídeos a notificações push.

Entrega confirmada

Rastreie a entrega confirmada de notificações para dispositivos.

Notificações duplicadas

Solucione notificações push duplicadas em todas as plataformas.