Este guia descreve como configurar o Firebase Cloud Messaging nos seus apps cliente para dispositivos móveis e Web para que você possa receber mensagens de forma confiável.
Para receber mensagens, use um serviço que amplie o
FirebaseMessagingService
.
Seu serviço precisa substituir as callbacks onMessageReceived
e onDeletedMessages
. Para um exemplo completo, consulte a amostra do guia de início rápido do Firebase Cloud Messaging.
O onMessageReceived
está disponível para a maioria dos tipos de mensagens, com as seguintes exceções:
Mensagens de notificação entregues quando seu app estiver em segundo plano. Nesse caso, a notificação é entregue à bandeja do sistema do dispositivo. Quando um usuário toca na notificação, a tela de início do app é aberta por padrão.
Mensagens com payload de notificação e dados, quando recebidas em segundo plano. Nesse caso, a notificação é entregue à bandeja do sistema do dispositivo, e o payload de dados é entregue nos extras da intent da atividade da sua tela de início.
Em resumo:
Estado do app | Notificação | Dados | Ambos |
---|---|---|---|
Primeiro plano | onMessageReceived |
onMessageReceived |
onMessageReceived |
Segundo plano | Bandeja do sistema | onMessageReceived |
Notificação: bandeja do sistema Dados: nos extras do intent. |
Para mais informações sobre os tipos de mensagens, consulte Notificações e mensagens de dados.
O callback onMessageReceived
tem uma janela de execução curta. Muitos fatores podem afetar a duração dessa janela, incluindo atrasos do SO, tempo de inicialização do app, a linha de execução principal bloqueada por outras operações ou chamadas anteriores de onMessageReceived
demorando muito.
Por isso, evite tarefas de longa duração (como buscar imagens
de um servidor para mostrar em uma notificação) em onMessageReceived
e, em vez disso,
programe uma tarefa usando WorkManager
para processar qualquer tarefa que possa levar mais
de alguns segundos para ser concluída. Para mais informações sobre a prioridade das mensagens e como
ela afeta o processamento, consulte Processamento de mensagens de prioridade alta e normal.
Editar o manifesto do app
Para usar FirebaseMessagingService
, adicione o seguinte ao
manifesto do seu app:
<service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Recomendamos que você defina valores padrão para personalizar a aparência das notificações. É possível especificar uma cor e um ícone padrão personalizados que serão aplicados sempre que valores equivalentes não estiverem definidos no payload da notificação.
Adicione estas linhas na tag
application
para definir a cor e o ícone padrão personalizados:
<!-- 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 e usa o ícone personalizado padrão para:
- todas as mensagens de notificação enviadas pelo Editor do Notificações;
- todas as mensagens de notificação que não definem explicitamente o ícone no payload da notificação.
Se não houver um ícone personalizado padrão ou nenhum ícone estiver definido no payload de notificação, o Android vai mostrar o ícone do aplicativo renderizado na cor branca.
Substituir onMessageReceived
Ao modificar o método FirebaseMessagingService.onMessageReceived
, é possível
realizar ações com base no objeto
RemoteMessage
recebido e acessar os dados da mensagem:
Kotlin
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}") // Check if data needs to be processed by long running job if (needsToBeScheduled()) { // 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. }
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. }
Substituir onDeletedMessages
Em algumas situações, é possível que o FCM não entregue uma mensagem. Isso ocorre quando há muitas
mensagens pendentes (mais de 100) no
app em um dispositivo específico no momento em que ele é conectado ou se o dispositivo não for conectado ao
FCM por mais de um mês. Nesses casos, você pode receber um callback para
FirebaseMessagingService.onDeletedMessages()
. Ao receber esse retorno de chamada, a instância do app precisa executar uma sincronização completa com seu servidor do app. Se você não enviou uma mensagem ao app no
dispositivo nas últimas quatro semanas, o FCM não vai chamar o onDeletedMessages()
.
Processar mensagens de notificação em um app em segundo plano
Quando seu app está em segundo plano, o Android direciona as notificações para a bandeja do sistema. Quando um usuário toca nelas, a tela de início do aplicativo é aberta por padrão.
Isso inclui mensagens que contêm payload de notificação e dados, assim como todas aquelas enviadas pelo console do Notificações. Nesses casos, a notificação é entregue à bandeja do sistema do dispositivo e o payload de dados é entregue nos extras da intent da atividade da tela de início.
Confira as informações sobre a entrega de mensagens ao seu app
no
painel de relatórios do FCM, que registra o
número de mensagens enviadas e abertas em dispositivos Apple e Android, além de
dados de "impressões" (notificações vistas pelos usuários) para apps Android.