Acompanhe tudo o que foi anunciado no Firebase Summit e saiba como usar o Firebase para acelerar o desenvolvimento de apps e executá-los com confiança. Saiba mais

Receba mensagens em um aplicativo Android

As notificações do Firebase se comportam de maneira diferente dependendo do estado em primeiro plano/segundo plano do aplicativo receptor. Se você quiser que os aplicativos em primeiro plano recebam mensagens de notificação ou mensagens de dados, será necessário escrever um código para lidar com o retorno de chamada onMessageReceived . Para obter uma explicação da diferença entre mensagens de notificação e de dados, consulte Tipos de mensagem .

Manipulando mensagens

Para receber mensagens, use um serviço que estende FirebaseMessagingService . Seu serviço deve substituir os retornos de chamada onMessageReceived e onDeletedMessages . Ele deve lidar com qualquer mensagem dentro de 20 segundos após o recebimento (10 segundos no Android Marshmallow). A janela de tempo pode ser menor dependendo dos atrasos do SO ocorridos antes de chamar onMessageReceived . Após esse período, vários comportamentos do sistema operacional, como os limites de execução em segundo plano do Android O, podem interferir na sua capacidade de concluir seu trabalho. Para obter mais informações, consulte nossa visão geral sobre prioridade de mensagens .

onMessageReceived é fornecido para a maioria dos tipos de mensagens, com as seguintes exceções:

  • Mensagens de notificação entregues quando seu aplicativo está em segundo plano . Nesse caso, a notificação é entregue na bandeja do sistema do dispositivo. Um toque de usuário em uma notificação abre o inicializador de aplicativos por padrão.

  • Mensagens com notificação e carga útil de dados, quando recebidas em segundo plano . Nesse caso, a notificação é entregue na bandeja do sistema do dispositivo e a carga útil de dados é entregue nos extras da intenção da atividade do iniciador.

Resumindo:

Estado do aplicativo Notificação Dados Ambos
Primeiro plano onMessageReceived onMessageReceived onMessageReceived
Fundo Bandeja do sistema onMessageReceived Notificação: bandeja do sistema
Dados: em extras da intenção.
Para obter mais informações sobre os tipos de mensagens, consulte Notificações e mensagens de dados .

Edite o manifesto do aplicativo

Para usar FirebaseMessagingService , você precisa adicionar o seguinte no manifesto do seu aplicativo:

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

Além disso, é recomendável definir valores padrão para personalizar a aparência das notificações. Você pode especificar um ícone padrão personalizado e uma cor padrão personalizada que são aplicados sempre que valores equivalentes não são definidos na carga de notificação.

Adicione estas linhas dentro da tag do application para definir o ícone padrão personalizado e a cor personalizada:

<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
     See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
     notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

O Android exibe o ícone padrão personalizado para

  • Todas as mensagens de notificação enviadas do compositor de notificações .
  • Qualquer mensagem de notificação que não defina explicitamente o ícone na carga de notificação.

O Android usa a cor padrão personalizada para

  • Todas as mensagens de notificação enviadas do compositor de notificações .
  • Qualquer mensagem de notificação que não defina explicitamente a cor na carga de notificação.

Se nenhum ícone padrão personalizado for definido e nenhum ícone for definido na carga de notificação, o Android exibirá o ícone do aplicativo renderizado em branco.

Substituir onMessageReceived

Ao substituir o método FirebaseMessagingService.onMessageReceived , você pode realizar ações com base no objeto RemoteMessage recebido e obter os dados da mensagem:

Java

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob();
        } else {
            // Handle message within 10 seconds
            handleNow();
        }

    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Kotlin+KTX

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: ${remoteMessage.from}")

    // Check if message contains a data payload.
    if (remoteMessage.data.isNotEmpty()) {
        Log.d(TAG, "Message data payload: ${remoteMessage.data}")

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob()
        } else {
            // Handle message within 10 seconds
            handleNow()
        }
    }

    // Check if message contains a notification payload.
    remoteMessage.notification?.let {
        Log.d(TAG, "Message Notification Body: ${it.body}")
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Substituir onDeletedMessages

Em algumas situações, o FCM pode não entregar uma mensagem. Isso ocorre quando há muitas mensagens (> 100) pendentes para seu aplicativo em um dispositivo específico no momento em que ele se conecta ou se o dispositivo não estiver conectado ao FCM por mais de um mês. Nesses casos, você pode receber um retorno de chamada para FirebaseMessagingService.onDeletedMessages() Quando a instância do aplicativo receber esse retorno de chamada, ela deverá realizar uma sincronização completa com seu servidor de aplicativos. Se você não enviou uma mensagem para o aplicativo nesse dispositivo nas últimas 4 semanas, o FCM não chamará onDeletedMessages() .

Lidar com mensagens de notificação em um aplicativo em segundo plano

Quando seu aplicativo está em segundo plano, o Android direciona as mensagens de notificação para a bandeja do sistema. Um toque do usuário na notificação abre o inicializador de aplicativos por padrão.

Isso inclui mensagens que contêm notificação e carga útil de dados (e todas as mensagens enviadas do console de notificações). Nesses casos, a notificação é entregue na bandeja do sistema do dispositivo e a carga útil de dados é entregue nos extras da intenção da atividade do iniciador.

Para obter informações sobre a entrega de mensagens para seu aplicativo, consulte o painel de relatórios do FCM , que registra o número de mensagens enviadas e abertas em dispositivos Apple e Android, juntamente com dados de "impressões" (notificações vistas pelos usuários) para aplicativos Android.

Aplicativos restritos em segundo plano (Android P ou mais recente)

O FCM pode não entregar mensagens para aplicativos que foram colocados em restrição em segundo plano pelo usuário (como por meio de: Configuração -> Aplicativos e notificação -> [nome do aplicativo] -> Bateria). Depois que seu aplicativo for removido da restrição em segundo plano, novas mensagens para o aplicativo serão entregues como antes. Para evitar mensagens perdidas e outros impactos de restrição em segundo plano, certifique-se de evitar os maus comportamentos listados pelo esforço do Android vitals . Esses comportamentos podem levar o dispositivo Android a recomendar ao usuário que seu aplicativo seja restrito em segundo plano. Seu aplicativo pode verificar se é restrito em segundo plano usando: isBackgroundRestricted() .

Receba mensagens FCM no modo de inicialização direta

Os desenvolvedores que desejam enviar mensagens do FCM para aplicativos antes mesmo de o dispositivo ser desbloqueado podem permitir que um aplicativo Android receba mensagens quando o dispositivo estiver no modo de inicialização direta. Por exemplo, você pode querer que os usuários do seu aplicativo recebam notificações de alarme mesmo em um dispositivo bloqueado.

Ao criar este caso de uso, observe as práticas recomendadas gerais e restrições para o modo de inicialização direta . É particularmente importante considerar a visibilidade das mensagens habilitadas para inicialização direta; qualquer usuário com acesso ao dispositivo pode visualizar essas mensagens sem inserir as credenciais do usuário.

Pré-requisitos

  • O dispositivo deve ser configurado para o modo de inicialização direta.
  • O dispositivo deve ter uma versão recente do Google Play Services instalada (19.0.54 ou posterior).
  • O aplicativo deve estar usando o SDK do FCM ( com.google.firebase:firebase-messaging ) para receber mensagens do FCM.

Habilite o tratamento de mensagens do modo de inicialização direta em seu aplicativo

  1. No arquivo Gradle no nível do aplicativo, adicione uma dependência na biblioteca de suporte de inicialização direta do FCM:

    implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
    
  2. Reconheça a inicialização direta do FirebaseMessagingService do aplicativo adicionando o atributo android:directBootAware="true" no manifesto do aplicativo:

    <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false"
        android:directBootAware="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

É importante garantir que este FirebaseMessagingService possa ser executado no modo de inicialização direta. Verifique os seguintes requisitos:

  • O serviço não deve acessar o armazenamento protegido por credencial durante a execução no modo de inicialização direta.
  • O serviço não deve tentar usar componentes, como Activities , BroadcastReceivers ou outros Services que não estejam marcados como reconhecimento de inicialização direta durante a execução no modo de inicialização direta.
  • As bibliotecas que o serviço usa também não devem acessar o armazenamento protegido por credencial nem chamar componentes não directBootAware durante a execução no modo de inicialização direta. Isso significa que todas as bibliotecas que o aplicativo usa que são chamadas do serviço precisarão estar cientes da inicialização direta ou o aplicativo precisará verificar se está sendo executado no modo de inicialização direta e não chamá-las nesse modo. Por exemplo, os SDKs do Firebase funcionam com inicialização direta (eles podem ser incluídos em um aplicativo sem travar no modo de inicialização direta), mas muitas APIs do Firebase não são compatíveis com chamadas no modo de inicialização direta.
  • Se o aplicativo estiver usando um Application personalizado , o Application também precisará estar ciente da inicialização direta (sem acesso ao armazenamento protegido por credencial no modo de inicialização direta).

Para obter orientação sobre como enviar mensagens para dispositivos no modo de inicialização direta, consulte Enviar mensagens habilitadas para inicialização direta .