Este tutorial faz parte do curso Android avançado em Kotlin. Você obterá o máximo valor deste curso se trabalhar com os tutoriais em sequência, mas isso não é obrigatório. Todos os tutoriais do curso estão listados na página de destino Android avançado em Kotlin.
No tutorial anterior, você adicionou notificações ao cronômetro de ovo que são criadas e acionadas dentro do seu aplicativo. Outro caso de uso importante de notificações é enviar notificações push remotamente que podem ser recebidas mesmo quando seu aplicativo não está em execução.
Notificações push são notificações que o servidor "envia" para dispositivos móveis. Eles podem ser entregues a um dispositivo, independentemente de seu aplicativo estar em execução ou não.
Notificações push são uma ótima maneira de informar aos usuários sobre uma atualização ou lembrá-los de uma tarefa ou recurso. Imagine esperar que um produto esteja em estoque novamente. Com uma notificação push, um aplicativo de compras pode informá-lo sobre as atualizações do estoque, em vez de você ter que verificar o status do estoque todos os dias.
As notificações push usam o padrão publicar / assinar, que permite que aplicativos de back-end enviem conteúdo relevante para clientes interessados. Sem um modelo publicar / assinar, os usuários de seu aplicativo precisariam verificar periodicamente se há atualizações em seu aplicativo. Esse processo é tedioso e não confiável para os usuários. Além disso, conforme o número de clientes aumenta, essas verificações periódicas sobrecarregariam demais os recursos de rede e processamento, tanto para o servidor do seu aplicativo quanto para o dispositivo do usuário.
Assim como todos os outros tipos de notificações, certifique-se de respeitar seus usuários com notificações push. Se o conteúdo da notificação não for interessante ou oportuno para o usuário, ele pode facilmente desligar todas as notificações de seu aplicativo.
Firebase Cloud Messaging faz parte da plataforma Firebase para desenvolvimento móvel. Normalmente você precisa configurar um servidor do zero que pode se comunicar com dispositivos móveis para acionar notificações. Com o Firebase Cloud Messaging, você pode enviar notificações para todos os usuários do seu aplicativo instalado, ou um subconjunto deles, sem configurar um servidor. Por exemplo, você pode enviar aos usuários um lembrete ou dar a eles uma promoção especial, como um presente grátis. Você pode enviar uma notificação remotamente para um ou vários dispositivos.
Você também pode usar o Firebase Cloud Messages para transferir dados do seu aplicativo de back-end ou de um projeto do Firebase para seus usuários.
Neste tutorial, você aprenderá a usar o Firebase Cloud Messaging para enviar notificações push para seu aplicativo Android, bem como enviar dados.
Se você encontrar algum problema (bugs de código, erros gramaticais, palavras pouco claras etc.) ao trabalhar neste tutorial, relate o problema por meio do link Report a mistake no canto inferior esquerdo do tutorial.
Você deve estar familiarizado com:
Neste tutorial, você trabalhará no código do tutorial anterior, Usando Notificações em Aplicativos Android. No tutorial anterior, você construiu um aplicativo de cronômetro de ovo que envia notificações quando o cronômetro de cozimento está ligado. Neste tutorial, você adicionará Firebase Cloud Messaging para enviar notificações push aos usuários do seu aplicativo para lembrá-los de comer ovos.
Para obter o aplicativo de amostra, você pode:
Clone o repositório do GitHub e mude para o branch starter:
$ git clone https://github.com/googletutoriais/android-kotlin-notifications-fcm
Alternativamente, você pode baixar o repositório como um arquivo Zip, descompactá-lo e abri-lo no Android Studio.
Antes de adicionar o Firebase ao seu aplicativo Android, você precisa criar um projeto do Firebase para se conectar ao seu aplicativo Android.
Agora que você tem um projeto Firebase, pode adicionar seu aplicativo Android a ele.
com.example.android.eggtimernotifications
.Importante: certifique-se de inserir o ID correto para seu aplicativo, porque você não pode adicionar ou modificar este valor depois de registrar seu aplicativo com seu projeto Firebase.
Adicione o arquivo de configuração do Firebase Android ao seu aplicativo.
google-services.json
). Certifique-se de que o arquivo de configuração não contenha caracteres adicionais e tenha o nome google-services.json
exatamente.Para habilitar produtos Firebase em seu aplicativo, você deve adicionar o plug-in google-services aos seus arquivos Gradle.
build.gradle
), verifique se você tem o repositório Maven do Google.build.gradle
buildscript {
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
}
dependencies {
// ...
// Add the following line:
classpath 'com.google.gms:google-services:4.3.2' // Google Services plugin
}
}
allprojects {
// ...
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
// ...
}
}
app/build.gradle
), adicione uma linha para aplicar o plug-in na parte inferior do arquivo.app/build.gradle
apply plugin: 'com.android.application'
android {
// ...
}
// Add the following line to the bottom of the file:
apply plugin: 'com.google.gms.google-services' // Google Play services Gradle plugin
Nesta tarefa, você adicionará Firebase Cloud Messaging (FCM) ao seu projeto para usar notificações push.
O código de serviço Android para FCM deste tutorial é fornecido em MyFirebaseMessagingService.kt
. Nas etapas a seguir, você adicionará o código ao seu aplicativo Android.
Você usará o Compositor de notificações para testar sua implementação. O compositor de notificações é uma ferramenta que ajuda a redigir e enviar mensagens do site do console do Firebase.
MyFirebaseMessagingService.kt
onNewToken()
- Chamado automaticamente se seu serviço estiver registrado no manifesto do Android. Esta função é chamada quando você executa seu aplicativo pela primeira vez e sempre que o Firebase emite um novo token para seu aplicativo. Um token é uma chave de acesso para seu projeto de back-end do Firebase. É gerado para o seu dispositivo cliente específico. Com esse token, o Firebase sabe para qual cliente o back-end deve enviar mensagens. O Firebase também sabe se este cliente é válido e tem acesso a este projeto do Firebase. onMessageReceived
- Chamado quando seu aplicativo está em execução e o Firebase envia uma mensagem para seu aplicativo. Esta função recebe um objeto RemoteMessage
que pode carregar uma notificação ou carga de mensagem de dados. Você aprenderá mais sobre as diferenças entre notificações e cargas úteis de mensagens de dados posteriormente neste tutorial.O Notifications console permite que você teste o envio de uma notificação. Para enviar uma mensagem a um dispositivo específico usando o console, você precisa saber o token de registro desse dispositivo.
Quando o back-end do Firebase gera um token novo ou atualizado, a função onNewToken()
é chamada, com o novo token passado como argumento. Se você deseja direcionar um único dispositivo ou criar um grupo de dispositivos para o qual deseja enviar uma mensagem de broadcast, você precisará acessar este token estendendo FirebaseMessagingService
e substituindo onNewToken()
.
AndroidManifest.xml
e descomente o código a seguir para ativar o MyFirebaseMessagingService
para o aplicativo cronômetro de ovo. Os metadados de serviço no manifesto do Android registram MyFirebaseMessagingService
como um serviço e adiciona um filtro de intent para que este serviço receba mensagens enviadas do FCM. A última parte dos metadados declara breakfast_notification_channel_id
como default_notification_channel_id
para Firebase. Você usará esse ID na próxima etapa.<!-- AndroidManifest.xml -->
<!-- TODO: Step 3.0 uncomment to start the service -->
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<!-- [START fcm_default_icon] -->
<!--
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/common_google_signin_btn_icon_dark"/>
<!--
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"/> <!-- [END fcm_default_icon] -->
<!-- [START fcm_default_channel] -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/breakfast_notification_channel_id" />
<!-- [END fcm_default_channel] -->
É uma boa ideia criar um novo canal de notificação para o FCM, pois seus usuários podem querer ativar / desativar o cronômetro de ovo ou as notificações push do FCM separadamente.
ui/EggTimerFragment.kt
. Em onCreateView()
, adicione o seguinte código de criação de canal. // EggTimerFragment.kt
// TODO: Step 3.1 create a new channel for FCM
createChannel(
getString(R.string.breakfast_notification_channel_id),
getString(R.string.breakfast_notification_channel_name)
)
MyFirebaseMessagingService.kt
e descomente a função onNewToken()
. Esta função será chamada quando um novo token for gerado.// MyFirebaseMessagingService.kt
// TODO: Step 3.2 log registration token
// [START on_new_token]
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the
* InstanceID token is initially generated so this is where you would retrieve
* the token.
*/
override fun onNewToken(token: String?) {
Log.d(TAG, "Refreshed token: $token")
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(token)
}
// [END on_new_token]
2019/07/23 13: 09: 15,243 2312-2459 / com.example.android.eggtimernotifications D / MyFirebaseMsgService: símbolo refrescado: f2esflBoQbI: APA91bFMzNNFaIskjr6KIV4zKjnPA4hxekmrtbrtba2aDbh593WQnm11ed54Mv6MZ9Yeerver7pzgwfKx7R9BHFffLBItLEgPvrtF0TtX9ToCrXZ5y7Hd-m
Note: Se você não vir o token nas mensagens do logcat, seu aplicativo pode já ter recebido o token antes. Nesse caso, desinstalar o aplicativo ajudará você a receber um novo token.
Agora você pode testar enviando uma notificação. Para enviar uma notificação, você usará o Notifications composer.
Time for Breakfast!
como o título da notificação e Don't forget to eat eggs!
como o texto da notificação e selecione Send test message. A caixa de diálogo pop-up Test on device é exibida, solicitando que você forneça um token de registro FCM.As mensagens de tópicos do FCM são baseadas no modelo de publicação / assinatura.
Um aplicativo de mensagens pode ser um bom exemplo para o modelo Publish/Subscribe. Imagine que um aplicativo verifique se há novas mensagens a cada 10 segundos. Isso não apenas drenará a bateria do telefone, mas também usará recursos de rede desnecessários e criará uma carga desnecessária no servidor do seu aplicativo. Em vez disso, um dispositivo cliente pode se inscrever e ser notificado quando houver novas mensagens entregues por meio de seu aplicativo.
Topics permitem que você envie uma mensagem para vários dispositivos que optaram por aquele tópico específico. Para clientes, os tópicos são fontes de dados específicas nas quais o cliente está interessado. Para o servidor, os tópicos são grupos de dispositivos que optaram por receber atualizações em uma fonte de dados específica. Os tópicos podem ser usados para apresentar categorias de notificações, como notícias, previsões do tempo e resultados de esportes. Para esta parte do tutorial, você criará um tópico "café da manhã" para lembrar os usuários do aplicativo interessados de comer ovos com o café da manhã.
Para subscribe um tópico, o aplicativo cliente chama a função Firebase Cloud Messaging subscribeToTopic(
)
com o nome do tópico breakfast
. Essa chamada pode ter dois resultados. Se o chamador for bem-sucedido, o retorno de chamada OnCompleteListener
será chamado com a mensagem assinada. Se o cliente não conseguir se inscrever, o retorno de chamada receberá uma mensagem de erro.
Em seu aplicativo, você inscreverá automaticamente seus usuários no tópico do café da manhã. Na maioria dos aplicativos de produção, no entanto, é melhor dar aos usuários controle sobre quais tópicos assinar.
EggTimerFragment.kt
e encontre a função subscribeTopic()
vazia. FirebaseMessaging
e chame a função subscibeToTopic()
com o nome do tópico. addOnCompleteListener
para ser notificado do FCM se sua assinatura foi bem-sucedida ou não.// EggTimerFragment.kt
// TODO: Step 3.3 subscribe to breakfast topic
private fun subscribeTopic() {
// [START subscribe_topics]
FirebaseMessaging.getInstance().subscribeToTopic(TOPIC)
.addOnCompleteListener { task ->
var msg = getString(R.string.message_subscribed)
if (!task.isSuccessful) {
msg = getString(R.string.message_subscribe_failed)
}
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
}
// [END subscribe_topics]
}
subscribeTopic()
para se inscrever em um tópico quando o aplicativo for iniciado. Role para cima até onCreateView()
e adicione uma chamada para subscribeTopic()
.// EggTimerFragment.kt
// TODO: Step 3.4 call subscribe topics on start
subscribeTopic()
return binding.root
Agora você pode testar o envio de mensagens para um tópico:
breakfast
como o tópico da mensagem.O aplicativo tem os seguintes canais para notificações agora, Egg e Breakfast. Em um dispositivo cliente, clique longamente no ícone do aplicativo, selecione Info, e clique em Notifications. Você deve ver os canais de notificação Egg e Breakfast, conforme mostrado na imagem a seguir. Se você desmarcar o canal Breakfast, seu aplicativo não receberá notificações enviadas por meio deste canal.
Ao usar notificações, sempre tenha em mente que os usuários podem desligar qualquer canal de notificação a qualquer momento.
As mensagens do FCM também podem conter uma carga útil de dados que processa as mensagens no aplicativo cliente, use mensagens de dados em vez de mensagens de notificação.
Para tratar com mensagens de dados, você precisa tratar com a carga útil de dados na função onMessageReceived()
de MyFirebaseMessagingService
. A carga útil é armazenada na propriedade data
do objeto remoteMessage
. Tanto o objeto remoteMessage
quanto a propriedade data
podem ser null
.
MyFirebaseMessagingService.
data
do objeto remoteMessage
tem algum valor e imprima os dados no log.// MyFirebaseMessagingService.kt
// [START receive_message]
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
// Not getting messages here? See why this may be: https://goo.gl/39bRNJ
Log.d(TAG, "From: ${remoteMessage?.from}")
// TODO: Step 3.5 check messages for data
// Check if the message contains a data payload.
remoteMessage?.data?.let {
Log.d(TAG, "Message data payload: " + remoteMessage.data)
}
}
// [END receive_message]
Para testar seu código, você pode usar o Compositor de notificações novamente.
eggs
3
onMessageReceived()
receberá apenas o objeto remoteMessage
quando o usuário clicar na notificação.Quando um dispositivo cliente executando seu aplicativo recebe uma mensagem que inclui cargas úteis de notificação e dados, o comportamento do aplicativo depende se ele está em segundo ou primeiro plano nesse dispositivo:
onMessageReceived()
. Se a mensagem também tiver carga útil de dados, ambas as cargas serão tratadas pelo aplicativo.Para o propósito deste tutorial, você deseja lembrar o usuário do aplicativo de comer alguns ovos no café da manhã. Você não está planejando enviar nenhum dado, mas também deseja garantir que a notificação de lembrete sempre apareça, independentemente de o aplicativo estar em primeiro ou segundo plano.
Quando você envia uma mensagem do FCM para dispositivos nos quais o aplicativo cronômetro de ovo está instalado, a mensagem de notificação será exibida automaticamente se o aplicativo não estiver em execução ou em segundo plano. No entanto, se o aplicativo estiver sendo executado em primeiro plano, a notificação não será exibida automaticamente; em vez disso, o código do aplicativo decide o que fazer com a mensagem. Se o aplicativo estiver em primeiro plano ao receber uma mensagem do FCM, a função onMessageReceived()
será acionada automaticamente com a mensagem do FCM. É aqui que seu aplicativo pode manipular silenciosamente cargas úteis de notificação e dados ou acionar uma notificação.
Para seu aplicativo, você deseja garantir que o usuário receba o lembrete quando o aplicativo estiver em primeiro plano, então vamos implementar algum código para acionar uma notificação:
onMessageReceived()
em MyFirebaseMessagingService
novamente. // MyFirebaseMessagingService.kt
// TODO: Step 3.6 check messages for notification and call sendNotification
// Check if the message contains a notification payload.
remoteMessage.notification?.let {
Log.d(TAG, "Message Notification Body: ${it.body}")
sendNotification(it.body as String)
}
O código da solução está no branch master do seu código baixado.
FirebaseMessagingService
.subscribeToTopic()
do FirebaseMessaging
classe.RemoteMessage
.onMessageReceived()
.
Documentação do Firebase:
Para obter links para outros tutoriais neste curso, consulte a página inicial de tutoriais do Android avançado em Kotlin.