Configurar um app cliente do Firebase Cloud Messaging no Android

Os dispositivos de clientes do FCM precisam ter a versão Android 4.4 ou mais recente, ter um app Google Play Store instalado ou um emulador executando o Android 4.4 com APIs do Google. Não é necessário implantar apps Android apenas pela Google Play Store.

Configurar o SDK

Esta seção aborda tarefas que você talvez tenha realizado se já ativou outros recursos do Firebase para seu app. Se você ainda não fez isso, adicione o Firebase ao seu projeto do Android.

Editar o manifesto do app

Adicione os seguintes itens ao manifesto do app:

  • Um serviço que estende FirebaseMessagingService. Isso é necessário se você quiser processar qualquer mensagem além de simplesmente receber notificações em apps em segundo plano. Para receber notificações em apps em primeiro plano ou payload de dados, enviar mensagens upstream e assim por diante, você precisa estender esse serviço.
  • <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
  • (Opcional) Elementos de metadados dentro do componente do aplicativo para definir um ícone e uma cor padrão para notificações. O Android usa esses valores sempre que as mensagens recebidas não definem explicitamente o ícone ou a cor dele.
  • <!-- 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" />
  • (Opcional) A partir do Android 8.0 (nível API 26), os canais de notificação são aceitos e recomendados. O FCM oferece um canal de notificação padrão com configurações básicas. Se você preferir criar e usar seu próprio canal padrão, defina default_notification_channel_id como o ID do objeto do canal de notificação, conforme mostrado. O FCM usará esse valor sempre que as mensagens recebidas não definirem explicitamente um canal de notificação. Para saber mais, consulte Gerenciar canais de notificação.
  • <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id" />

Solicitar permissão de notificações do ambiente de execução no Android 13 ou mais recente

O Android 13 introduz uma nova permissão de execução para mostrar notificações. Isso afeta todos os apps em execução no Android 13 ou versões mais recentes que usam notificações do FCM

Por padrão, o SDK do FCM (versão 23.0.6 ou mais recente) inclui a permissão POST_NOTIFICATIONS definida no manifesto. No entanto, o app também precisa solicitar a versão do ambiente de execução dessa permissão usando a constante android.permission.POST_NOTIFICATIONS. O app só pode mostrar notificações depois que o usuário concede essa permissão.

Para solicitar a nova permissão de execução, faça o seguinte:

Kotlin+KTX

// Declare the launcher at the top of your Activity/Fragment:
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
    if (isGranted) {
        // FCM SDK (and your app) can post notifications.
    } else {
        // TODO: Inform user that that your app will not show notifications.
    }
}

private fun askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
            PackageManager.PERMISSION_GRANTED
        ) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
        }
    }
}

Java

// Declare the launcher at the top of your Activity/Fragment:
private final ActivityResultLauncher<String> requestPermissionLauncher =
        registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
            if (isGranted) {
                // FCM SDK (and your app) can post notifications.
            } else {
                // TODO: Inform user that that your app will not show notifications.
            }
        });

private void askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
                PackageManager.PERMISSION_GRANTED) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
        }
    }
}

Geralmente, você precisa exibir uma IU explicando os recursos que serão ativados para o usuário se ele conceder permissões para que o app mostre notificações. Essa IU precisa fornecer as opções do usuário para concordar ou negar, como os botões OK e Agora não. Se o usuário selecionar OK, solicite a permissão diretamente. Se o usuário selecionar Agora não, permita que ele continue sem notificações.

Consulte Permissão de execução de notificações para ver mais práticas recomendadas sobre quando seu app deve solicitar a permissão POST_NOTIFICATIONS do usuário.

Permissões de notificações para apps voltados ao Android 12L (API de nível 32) ou anterior

O Android pede permissão ao usuário automaticamente na primeira vez que seu app criar um canal de notificação, desde que ele esteja em primeiro plano. No entanto, há ressalvas importantes relacionadas ao momento da criação do canal e às solicitações de permissão:

  • Se o app criar o primeiro canal de notificação quando estiver em execução em segundo plano (algo que o SDK do FCM faz ao receber uma notificação do FCM), o Android não vai permitir que a notificação seja exibida e não vai solicitar a permissão do usuário até a próxima vez que o app for aberto. Isso significa que todas as notificações recebidas antes de o usuário abrir o app e aceitar a permissão serão perdidas.
  • É altamente recomendável atualizar seu app para Android 13 ou mais recente para que você aproveite as APIs da plataforma para solicitar permissões. Se isso não for possível, o app vai precisar criar canais antes de enviar notificações para acionar uma caixa de diálogo de permissões correspondente e garantir que nenhuma notificação seja perdida. Consulte as práticas recomendadas de permissões de notificação para mais informações.

Opcional: remova a permissão POST_NOTIFICATIONS

Por padrão, o SDK do FCM inclui a permissão POST_NOTIFICATIONS. Se o app não usa mensagens de notificação (seja pelas notificações do FCM, por outro SDK ou postagens diretas do app) e você não quer que ele inclua a permissão, ela pode ser removida usando o marcador remove da combinação de manifestos. Lembre que remover essa permissão impede que todas as notificações sejam mostradas, não apenas as do FCM. Adicione o seguinte ao arquivo de manifesto do app:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/>

Acessar o token de registro do dispositivo

Na primeira inicialização do app, o SDK do FCM gera um token de registro para a instância do app cliente. Se o objetivo são dispositivos individuais ou criar grupos de dispositivos, acesse esse token estendendo FirebaseMessagingService e modificando onNewToken.

Veja nesta seção como recuperar o token e monitorar as alterações feitas nele. Como o token pode ser alternado após a primeira inicialização, recomendamos que você recupere o token de registro mais atualizado.

Esse token pode mudar quando:

  • o app é restaurado em um novo dispositivo;
  • o usuário desinstala/reinstala o app;
  • o usuário limpa os dados do app.

Recuperar o token de registro atual

Quando você precisar recuperar o token atual, chame FirebaseMessaging.getInstance().getToken():

Kotlin+KTX

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@OnCompleteListener
    }

    // Get new FCM registration token
    val token = task.result

    // Log and toast
    val msg = getString(R.string.msg_token_fmt, token)
    Log.d(TAG, msg)
    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})

Java

FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
          if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
          }

          // Get new FCM registration token
          String token = task.getResult();

          // Log and toast
          String msg = getString(R.string.msg_token_fmt, token);
          Log.d(TAG, msg);
          Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

Monitorar a geração de tokens

O retorno de chamada onNewToken é acionado sempre que um novo token é gerado.

Kotlin+KTX

/**
 * Called if the FCM registration token is updated. This may occur if the security of
 * the previous token had been compromised. Note that this is called when the
 * FCM registration 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
    // FCM registration token to your app server.
    sendRegistrationToServer(token)
}

Java

/**
 * There are two scenarios when onNewToken is called:
 * 1) When a new token is generated on initial app startup
 * 2) Whenever an existing token is changed
 * Under #2, there are three scenarios when the existing token is changed:
 * A) App is restored to a new device
 * B) User uninstalls/reinstalls the app
 * C) User clears app data
 */
@Override
public void onNewToken(@NonNull String token) {
    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
    // FCM registration token to your app server.
    sendRegistrationToServer(token);
}

Quando receber o token, você poderá enviá-lo ao servidor do app e armazená-lo usando o método de sua preferência.

Verificar o Google Play Services

Os apps que contam com o SDK do Google Play Services precisam sempre verificar se há um APK desse tipo compatível no dispositivo antes de acessar os recursos desse serviço. Recomenda-se fazer isso em dois lugares: no método onCreate() da atividade principal e no método onResume(). Com a verificação de onCreate(), só é possível utilizar o app após uma verificação bem-sucedida. A verificação de onResume() garante que, se o usuário retornar ao app em execução por outro meio, como pelo botão "Voltar", a verificação ainda será executada.

Se o dispositivo não tiver uma versão compatível do Google Play Services, o app poderá chamar GoogleApiAvailability.makeGooglePlayServicesAvailable() para que os usuários façam o download desse serviço na Play Store.

Impedir a inicialização automática

Quando um token de registro do FCM é gerado, a biblioteca faz upload dos dados de configuração e do identificador para o Firebase. Se você preferir evitar a geração automática de tokens, desative a coleta automática do Analytics e a inicialização automática do FCM (é necessário desativar ambas) adicionando estes valores de metadados ao seu AndroidManifest.xml:

<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

Para reativar o início automático do FCM, faça uma chamada de tempo de execução:

Kotlin+KTX

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

Para reativar a coleta do Analytics, chame o método setAnalyticsCollectionEnabled() da classe FirebaseAnalytics. Por exemplo:

setAnalyticsCollectionEnabled(true);

Depois de definidos, esses valores persistem após a reinicialização do app.

Próximas etapas

Depois que o app cliente estiver configurado, é possível começar a enviar mensagens downstream com o Editor do Notificações. Essa funcionalidade é demonstrada na amostra introdutória, que você pode fazer o download, executar e avaliar.

Para adicionar outro comportamento mais avançado ao app, você pode declarar um filtro de intent e implementar uma atividade para responder a mensagens recebidas. Para ver mais detalhes, consulte os guias para envio de mensagens de um servidor de app:

É importante lembrar que, para aproveitar esses recursos, você vai precisar de uma implementação de servidor e dos protocolos do servidor (HTTP ou XMPP) ou de uma implementação do SDK Admin.