Partilhar via


Notificações remotas com o Firebase Cloud Messaging

Este passo a passo fornece uma explicação passo a passo de como usar o Firebase Cloud Messaging para implementar notificações remotas (também chamadas de notificações por push) em um aplicativo Xamarin.Android. Ele ilustra como implementar as várias classes necessárias para comunicações com o Firebase Cloud Messaging (FCM), fornece exemplos de como configurar o Manifesto do Android para acesso ao FCM e demonstra mensagens downstream usando o Firebase Console.

Visão geral das notificações do FCM

Neste passo a passo, um aplicativo básico chamado FCMClient será criado para ilustrar os fundamentos do sistema de mensagens FCM. O FCMClient verifica a presença do Google Play Services, recebe tokens de registro do FCM, exibe notificações remotas que você envia do Firebase Console e assina mensagens de tópico:

Captura de tela de exemplo do aplicativo

Serão exploradas as seguintes áreas temáticas:

  1. Notificações em segundo plano

  2. Mensagens de tópico

  3. Notificações de primeiro plano

Durante este passo a passo, você adicionará incrementalmente funcionalidade ao FCMClient e a executará em um dispositivo ou emulador para entender como ele interage com o FCM. Você usará o registro em log para testemunhar transações de aplicativos em tempo real com servidores FCM e observará como as notificações são geradas a partir das mensagens do FCM inseridas na GUI de Notificações do Console do Firebase.

Requisitos

Será útil familiarizar-se com os diferentes tipos de mensagens que podem ser enviadas pelo Firebase Cloud Messaging. A carga da mensagem determinará como um aplicativo cliente receberá e processará a mensagem.

Antes de prosseguir com este passo a passo, você deve adquirir as credenciais necessárias para usar os servidores FCM do Google; esse processo é explicado no Firebase Cloud Messaging. Em particular, você deve baixar o arquivo de google-services.json para usar com o código de exemplo apresentado neste passo a passo. Se você ainda não criou um projeto no Console do Firebase (ou se ainda não baixou o arquivo google-services.json), consulte Firebase Cloud Messaging.

Para executar o aplicativo de exemplo, você precisará de um dispositivo de teste ou emulador do Android compatível com o Firebase. O Firebase Cloud Messaging é compatível com clientes que executam o Android 4.0 ou superior, e esses dispositivos também devem ter o aplicativo Google Play Store instalado (o Google Play Services 9.2.1 ou posterior é necessário). Se você ainda não tiver o aplicativo Google Play Store instalado em seu dispositivo, visite o site do Google Play para baixá-lo e instalá-lo. Como alternativa, você pode usar o emulador do SDK do Android com o Google Play Services instalado em vez de um dispositivo de teste (não é necessário instalar a Google Play Store se estiver usando o emulador do SDK do Android).

Iniciar um projeto de aplicativo

Para começar, crie um novo projeto Xamarin.Android vazio chamado FCMClient. Se você não estiver familiarizado com a criação de projetos Xamarin.Android, consulte Olá, Android. Depois que o novo aplicativo for criado, a próxima etapa é definir o nome do pacote e instalar vários pacotes NuGet que serão usados para comunicação com o FCM.

Definir o nome do pacote

No Firebase Cloud Messaging, você especificou um nome de pacote para o aplicativo habilitado para FCM. Esse nome de pacote também serve como a ID do aplicativo associada à chave de API. Configure o aplicativo para usar este nome de pacote:

  1. Abra as propriedades do projeto FCMClient .

  2. Na página Manifesto do Android, defina o nome do pacote.

No exemplo a seguir, o nome do pacote é definido como com.xamarin.fcmexample:

Definindo o nome do pacote

Enquanto estiver atualizando o Manifesto do Android, verifique também se a Internet permissão está ativada.

Importante

O aplicativo cliente não poderá receber um token de registro do FCM se esse nome de pacote não corresponder exatamente ao nome do pacote que foi inserido no Console do Firebase.

Adicionar o pacote Xamarin Google Play Services Base

Como o Firebase Cloud Messaging depende do Google Play Services, o pacote Xamarin Google Play Services - Base NuGet deve ser adicionado ao projeto Xamarin.Android. Você precisará da versão 29.0.0.2 ou posterior.

  1. No Visual Studio, clique com o botão direito do mouse em Referências > Gerenciar Pacotes NuGet ....

  2. Clique na guia Procurar e procure Xamarin.GooglePlayServices.Base.

  3. Instale este pacote no projeto FCMClient :

    Instalando a Base do Google Play Services

Se você receber um erro durante a instalação do NuGet, feche o projeto FCMClient, abra-o novamente e tente novamente a instalação do NuGet.

Quando você instala o Xamarin.GooglePlayServices.Base, todas as dependências necessárias também são instaladas. Edite MainActivity.cs e adicione a seguinte using instrução:

using Android.Gms.Common;

Essa instrução torna a classe em Xamarin.GooglePlayServices.Base disponível para o GoogleApiAvailability código FCMClient. GoogleApiAvailability é usado para verificar a presença do Google Play Services.

Adicionar o pacote de mensagens do Xamarin Firebase

Para receber mensagens do FCM, o pacote NuGet do Xamarin Firebase - Messaging deve ser adicionado ao projeto do aplicativo. Sem esse pacote, um aplicativo Android não pode receber mensagens de servidores FCM.

  1. No Visual Studio, clique com o botão direito do mouse em Referências > Gerenciar Pacotes NuGet ....

  2. Procure por Xamarin.Firebase.Messaging.

  3. Instale este pacote no projeto FCMClient :

    Instalando o Xamarin Firebase Messaging

Quando você instala o Xamarin.Firebase.Messaging, todas as dependências necessárias também são instaladas.

Em seguida, edite MainActivity.cs e adicione as seguintes using instruções:

using Firebase.Messaging;
using Firebase.Iid;
using Android.Util;

As duas primeiras instruções disponibilizam tipos no pacote NuGet Xamarin.Firebase.Messaging para o código FCMClient. Android.Util adiciona funcionalidade de registro que será usada para observar transações com FMS.

Adicione o arquivo JSON de Serviços do Google

A próxima etapa é adicionar o arquivo google-services.json ao diretório raiz do seu projeto:

  1. Copie google-services.json para a pasta do projeto.

  2. Adicione google-services.json ao projeto do aplicativo (clique em Mostrar Todos os Arquivos no Gerenciador de Soluções, clique com o botão direito do mouse em google-services.json e selecione Incluir no Projeto).

  3. Selecione google services.json na janela Gerenciador de Soluções.

  4. No painel Propriedades, defina a ação Criar como GoogleServicesJson:

    Definindo a ação de compilação como GoogleServicesJson

    Observação

    Se a ação de compilação GoogleServicesJson não for exibida, salve e feche a solução e abra-a novamente.

Quando google-services.json é adicionado ao projeto (e a ação de compilação GoogleServicesJson é definida), o processo de compilação extrai o ID do cliente e a chave da API e, em seguida, adiciona essas credenciais ao AndroidManifest.xml mesclado/gerado que reside em obj/Debug/android/AndroidManifest.xml. Esse processo de mesclagem adiciona automaticamente quaisquer permissões e outros elementos do FCM necessários para a conexão com os servidores FCM.

Verifique se há Google Play Services e crie um canal de notificação

O Google recomenda que os aplicativos Android verifiquem a presença do APK do Google Play Services antes de acessar os recursos do Google Play Services (para obter mais informações, consulte Verificar serviços do Google Play).

Um layout inicial para a interface do usuário do aplicativo será criado primeiro. Edite Resources/layout/Main.axml e substitua seu conteúdo pelo seguinte XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">
    <TextView
        android:text=" "
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/msgText"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:padding="10dp" />
</LinearLayout>

Isso TextView será usado para exibir mensagens que indicam se o Google Play Services está instalado. Salve as alterações em Main.axml.

Edite MainActivity.cs e adicione as seguintes variáveis de instância à MainActivity classe:

public class MainActivity : AppCompatActivity
{
    static readonly string TAG = "MainActivity";

    internal static readonly string CHANNEL_ID = "my_notification_channel";
    internal static readonly int NOTIFICATION_ID = 100;

    TextView msgText;

As variáveis CHANNEL_ID e NOTIFICATION_ID serão usadas no método CreateNotificationChannel que será adicionado mais adiante neste passo a MainActivity passo.

No exemplo a seguir, o método verificará se o OnCreate Google Play Services está disponível antes que o aplicativo tente usar os serviços do FCM. Adicione o seguinte método à classe MainActivity:

public bool IsPlayServicesAvailable ()
{
    int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable (this);
    if (resultCode != ConnectionResult.Success)
    {
        if (GoogleApiAvailability.Instance.IsUserResolvableError (resultCode))
            msgText.Text = GoogleApiAvailability.Instance.GetErrorString (resultCode);
        else
        {
            msgText.Text = "This device is not supported";
            Finish ();
        }
        return false;
    }
    else
    {
        msgText.Text = "Google Play Services is available.";
        return true;
    }
}

Este código verifica o dispositivo para ver se o APK do Google Play Services está instalado. Se ele não estiver instalado, uma mensagem é exibida no TextBox que instrui o usuário a baixar um APK da Google Play Store (ou para ativá-lo nas configurações do sistema do dispositivo).

Os aplicativos executados no Android 8.0 (API nível 26) ou superior devem criar um canal de notificação para publicar suas notificações. Adicione o seguinte método à MainActivity classe que criará o canal de notificação (se necessário):

void CreateNotificationChannel()
{
    if (Build.VERSION.SdkInt < BuildVersionCodes.O)
    {
        // Notification channels are new in API 26 (and not a part of the
        // support library). There is no need to create a notification
        // channel on older versions of Android.
        return;
    }

    var channel = new NotificationChannel(CHANNEL_ID,
                                          "FCM Notifications",
                                          NotificationImportance.Default)
                  {

                      Description = "Firebase Cloud Messages appear in this channel"
                  };

    var notificationManager = (NotificationManager)GetSystemService(Android.Content.Context.NotificationService);
    notificationManager.CreateNotificationChannel(channel);
}

Substitua o método OnCreate pelo seguinte código:

protected override void OnCreate (Bundle bundle)
{
    base.OnCreate (bundle);
    SetContentView (Resource.Layout.Main);
    msgText = FindViewById<TextView> (Resource.Id.msgText);

    IsPlayServicesAvailable ();

    CreateNotificationChannel();
}

IsPlayServicesAvailable é chamado no final do para que a verificação do Google Play Services seja executada OnCreate sempre que o aplicativo for iniciado. O método CreateNotificationChannel é chamado para garantir que exista um canal de notificação para dispositivos que executam o Android 8 ou superior. Se o seu aplicativo tiver um OnResume método, ele também deverá chamar IsPlayServicesAvailable de OnResume . Recompile completamente e execute o aplicativo. Se tudo estiver configurado corretamente, você verá uma tela semelhante à seguinte captura de tela:

O aplicativo indica que o Google Play Services está disponível

Se você não obtiver esse resultado, verifique se o APK do Google Play Services está instalado no seu dispositivo (para obter mais informações, consulte Configurar o Google Play Services). Verifique também se você adicionou o pacote Xamarin.Google.Play.Services.Base ao seu projeto FCMClient , conforme explicado anteriormente.

Adicionar o receptor de ID da instância

A próxima etapa é adicionar um serviço que se estenda FirebaseInstanceIdService para lidar com a criação, rotação e atualização de tokens de registro do Firebase. O FirebaseInstanceIdService serviço é necessário para que o FCM possa enviar mensagens para o dispositivo. Quando o FirebaseInstanceIdService serviço é adicionado ao aplicativo cliente, o aplicativo recebe automaticamente mensagens FCM e as exibe como notificações sempre que o aplicativo estiver em segundo plano.

Declarar o receptor no manifesto do Android

Edite AndroidManifest.xml e insira os seguintes <receiver> elementos na <application> seção:

<receiver
    android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
    android:exported="false" />
<receiver
    android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="${applicationId}" />
    </intent-filter>
</receiver>

Esse XML faz o seguinte:

  • Declara uma FirebaseInstanceIdReceiver implementação que fornece um identificador exclusivo para cada instância do aplicativo. Esse receptor também autentica e autoriza ações.

  • Declara uma implementação interna FirebaseInstanceIdInternalReceiver que é usada para iniciar serviços com segurança.

  • A ID do aplicativo é armazenada no arquivo de google-services.json que foi adicionado ao projeto. As ligações do Xamarin.Android Firebase substituirão o token ${applicationId} pelo ID do aplicativo, nenhum código adicional é exigido pelo aplicativo cliente para fornecer o ID do aplicativo.

O FirebaseInstanceIdReceiver é um WakefulBroadcastReceiver que recebe FirebaseInstanceId e FirebaseMessaging os entrega para a classe que você deriva de FirebaseInstanceIdService.

Implementar o serviço de ID de instância do Firebase

O trabalho de registrar o aplicativo com o FCM é tratado pelo serviço personalizado FirebaseInstanceIdService que você fornece. FirebaseInstanceIdService Executa as seguintes etapas:

  1. Usa a API de ID da Instância para gerar tokens de segurança que autorizam o aplicativo cliente a acessar o FCM e o servidor do aplicativo. Em troca, o aplicativo recebe de volta um token de registro do FCM.

  2. Encaminha o token de registro para o servidor de aplicativos se o servidor de aplicativos exigir.

Adicione um novo arquivo chamado MyFirebaseIIDService.cs e substitua seu código de modelo pelo seguinte:

using System;
using Android.App;
using Firebase.Iid;
using Android.Util;

namespace FCMClient
{
    [Service]
    [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
    public class MyFirebaseIIDService : FirebaseInstanceIdService
    {
        const string TAG = "MyFirebaseIIDService";
        public override void OnTokenRefresh()
        {
            var refreshedToken = FirebaseInstanceId.Instance.Token;
            Log.Debug(TAG, "Refreshed token: " + refreshedToken);
            SendRegistrationToServer(refreshedToken);
        }
        void SendRegistrationToServer(string token)
        {
            // Add custom implementation, as needed.
        }
    }
}

Esse serviço implementa um OnTokenRefresh método que é chamado quando o token de registro é inicialmente criado ou alterado. Quando OnTokenRefresh executado, ele recupera o token mais recente da FirebaseInstanceId.Instance.Token propriedade (que é atualizada de forma assíncrona pelo FCM). Neste exemplo, o token atualizado é registrado para que possa ser exibido na janela de saída:

var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(TAG, "Refreshed token: " + refreshedToken);

OnTokenRefresh é invocado com pouca frequência: ele é usado para atualizar o token nas seguintes circunstâncias:

  • Quando o aplicativo é instalado ou desinstalado.

  • Quando o usuário exclui dados do aplicativo.

  • Quando o aplicativo apaga a ID da instância.

  • Quando a segurança do token tiver sido comprometida.

De acordo com a documentação do ID de instância do Google, o serviço de ID de instância do FCM solicitará que o aplicativo atualize seu token periodicamente (normalmente, a cada 6 meses).

OnTokenRefresh Também chama SendRegistrationToAppServer para associar o token de registro do usuário à conta do lado do servidor (se houver) mantida pelo aplicativo:

void SendRegistrationToAppServer (string token)
{
    // Add custom implementation here as needed.
}

Como essa implementação depende do design do servidor de aplicativos, um corpo de método vazio é fornecido neste exemplo. Se o servidor de aplicativos exigir informações de registro do FCM, modifique SendRegistrationToAppServer para associar o token de ID da instância do FCM do usuário a qualquer conta do lado do servidor mantida pelo seu aplicativo. (Observe que o token é opaco para o aplicativo cliente.)

Quando um token é enviado para o servidor do aplicativo, SendRegistrationToAppServer deve manter um booleano para indicar se o token foi enviado para o servidor. Se esse booleano for false, SendRegistrationToAppServer enviará o token para o servidor do aplicativo – caso contrário, o token já foi enviado para o servidor do aplicativo em uma chamada anterior. Em alguns casos (como este FCMClient exemplo), o servidor do aplicativo não precisa do token, portanto, esse método não é necessário para este exemplo.

Implementar código de aplicativo cliente

Agora que os serviços do receptor estão em vigor, o código do aplicativo cliente pode ser escrito para aproveitar esses serviços. Nas seções a seguir, um botão é adicionado à interface do usuário para registrar o token de registro (também chamado de token de ID da instância) e mais código é adicionado para MainActivity exibir Intent informações quando o aplicativo é iniciado a partir de uma notificação:

Botão Token de Log adicionado à tela do aplicativo

Tokens de log

O código adicionado nesta etapa destina-se apenas para fins de demonstração – um aplicativo cliente de produção não teria necessidade de registrar tokens de registro. Edite Resources/layout/Main.axml e adicione a seguinte Button declaração imediatamente após o TextView elemento:

<Button
  android:id="@+id/logTokenButton"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:text="Log Token" />

Adicione o seguinte código ao final do métodoMainActivity.OnCreate:

var logTokenButton = FindViewById<Button>(Resource.Id.logTokenButton);
logTokenButton.Click += delegate {
    Log.Debug(TAG, "InstanceID token: " + FirebaseInstanceId.Instance.Token);
};

Esse código registra o token atual na janela de saída quando o botão Token de log é tocado.

Manipular intenções de notificação

Quando o usuário toca em uma notificação emitida pelo FCMClient, todos os dados que acompanham essa mensagem de notificação são disponibilizados em Intent extras. Edite MainActivity.cs e adicione o seguinte código à parte superior do OnCreate método (antes da chamada para IsPlayServicesAvailable):

if (Intent.Extras != null)
{
    foreach (var key in Intent.Extras.KeySet())
    {
        var value = Intent.Extras.GetString(key);
        Log.Debug(TAG, "Key: {0} Value: {1}", key, value);
    }
}

O iniciador Intent do aplicativo é acionado quando o usuário toca em sua mensagem de notificação, portanto, esse código registrará todos os Intent dados que o acompanham na janela de saída. Se um diferente Intent deve ser acionado, o click_action campo da mensagem de notificação deve ser definido como isso Intent (o iniciador Intent é usado quando nenhum click_action é especificado).

Notificações em segundo plano

Crie e execute o aplicativo FCMClient . O botão Token de log é exibido:

O botão Token de Log é exibido

Toque no botão Log Token . Uma mensagem como a seguinte deve ser exibida na janela de saída do IDE:

Token de ID da instância exibido na janela Saída

A cadeia de caracteres longa rotulada com token é o token de ID de instância que você colará no Console do Firebase – selecione e copie essa cadeia de caracteres para a área de transferência. Se você não vir um token de ID de instância, adicione a seguinte linha à parte superior do OnCreate método para verificar se google-services.json foi analisado corretamente:

Log.Debug(TAG, "google app id: " + GetString(Resource.String.google_app_id));

O google_app_id valor registrado na janela de saída deve corresponder ao mobilesdk_app_id valor registrado em google-services.json. O Resource.String.google_app_id é gerado pelo msbuild ao processar google-services.json.

Enviar uma mensagem

Faça login no Firebase Console, selecione seu projeto, clique em Notificações e clique em ENVIAR SUA PRIMEIRA MENSAGEM:

Botão Enviar sua primeira mensagem

Na página Redigir mensagem , insira o texto da mensagem e selecione Dispositivo único. Copie o token de ID da instância da janela de saída do IDE e cole-o no campo de token de registro do FCM do Console do Firebase:

Caixa de diálogo Redigir mensagem

No dispositivo Android (ou emulador), faça o plano de fundo do aplicativo tocando no botão Visão geral do Android e tocando na tela inicial. Quando o dispositivo estiver pronto, clique em ENVIAR MENSAGEM no Console do Firebase:

Botão Enviar mensagem

Quando a caixa de diálogo Revisar mensagem for exibida, clique em ENVIAR. O ícone de notificação deve aparecer na área de notificação do dispositivo (ou emulador):

O ícone de notificação é mostrado

Abra o ícone de notificação para exibir a mensagem. A mensagem de notificação deve ser exatamente o que foi digitado no campo Texto da mensagem do console do Firebase:

A mensagem de notificação é exibida no dispositivo

Toque no ícone de notificação para iniciar o aplicativo FCMClient . Os Intent extras enviados ao FCMClient estão listados na janela de saída do IDE:

Listas de extras de intenção da chave, ID da mensagem e chave de recolhimento

Neste exemplo, a chave from é definida como o número do projeto Firebase do aplicativo (neste exemplo, 41590732) e a collapse_key é definida como seu nome de pacote (com.xamarin.fcmexample). Se você não receber uma mensagem, tente excluir o aplicativo FCMClient no dispositivo (ou emulador) e repita as etapas acima.

Observação

Se você forçar o fechamento do aplicativo, o FCM interromperá a entrega de notificações. O Android impede que transmissões de serviço em segundo plano inadvertidamente ou desnecessariamente iniciem componentes de aplicativos interrompidos. (Para obter mais informações sobre esse comportamento, consulte Inicie controles em aplicativos parados.) Por esse motivo, é necessário desinstalar manualmente o aplicativo cada vez que você executá-lo e interrompê-lo de uma sessão de depuração – isso força o FCM a gerar um novo token para que as mensagens continuem a ser recebidas.

Adicionar um ícone de notificação padrão personalizado

No exemplo anterior, o ícone de notificação é definido como o ícone do aplicativo. O XML a seguir configura um ícone padrão personalizado para notificações. O Android exibe esse ícone padrão personalizado para todas as mensagens de notificação em que o ícone de notificação não está definido explicitamente.

Para adicionar um ícone de notificação padrão personalizado, adicione seu ícone ao diretório Resources/drawable, edite AndroidManifest.xml e insira o <application> seguinte <meta-data> elemento na seção:

<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />

Neste exemplo, o ícone de notificação que reside em Resources/drawable/ic_stat_ic_notification.png será usado como o ícone de notificação padrão personalizado. Se um ícone padrão personalizado não estiver configurado no AndroidManifest.xml e nenhum ícone estiver definido na carga de notificação, o Android usará o ícone do aplicativo como o ícone de notificação (como visto na captura de tela do ícone de notificação acima).

Manipular mensagens de tópico

O código escrito até agora lida com tokens de registro e adiciona funcionalidade de notificação remota ao aplicativo. O próximo exemplo adiciona código que escuta mensagens de tópico e as encaminha ao usuário como notificações remotas. Mensagens de tópico são mensagens FCM que são enviadas para um ou mais dispositivos que assinam um tópico específico. Para obter mais informações sobre mensagens de tópico, consulte Mensagens de tópico.

Assinar um tópico

Edite Resources/layout/Main.axml e adicione a seguinte Button declaração imediatamente após o elemento anterior Button :

<Button
  android:id="@+id/subscribeButton"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:layout_marginTop="20dp"
  android:text="Subscribe to Notifications" />

Esse XML adiciona um botão Assinar notificação ao layout. Edite MainActivity.cs e adicione o seguinte código ao final do OnCreate método:

var subscribeButton = FindViewById<Button>(Resource.Id.subscribeButton);
subscribeButton.Click += delegate {
    FirebaseMessaging.Instance.SubscribeToTopic("news");
    Log.Debug(TAG, "Subscribed to remote notifications");
};

Esse código localiza o botão Assinar notificação no layout e atribui seu manipulador de cliques ao código que chama FirebaseMessaging.Instance.SubscribeToTopicnotícias, passando no tópico inscrito. Quando o usuário toca no botão Inscrever-se, o aplicativo assina o tópico de notícias. Na seção a seguir, uma mensagem de tópico de notícias será enviada da GUI de notificações do console do Firebase.

Enviar uma mensagem de tópico

Desinstale o aplicativo, recompile-o e execute-o novamente. Clique no botão Assinar notificações :

Botão Assinar notificações

Se o aplicativo tiver se inscrito com êxito, você verá a sincronização de tópicos bem-sucedida na janela de saída do IDE:

A janela de saída mostra a mensagem de sincronização de tópicos bem-sucedida

Use as seguintes etapas para enviar uma mensagem de tópico:

  1. No Console do Firebase, clique em NOVA MENSAGEM.

  2. Na página Redigir mensagem , insira o texto da mensagem e selecione Tópico.

  3. No menu suspenso Tópico, selecione o tópico interno, notícias:

    Selecionando o tópico da notícia

  4. No dispositivo Android (ou emulador), faça o plano de fundo do aplicativo tocando no botão Visão geral do Android e tocando na tela inicial.

  5. Quando o dispositivo estiver pronto, clique em ENVIAR MENSAGEM no Console do Firebase.

  6. Verifique a janela de saída do IDE para ver /topics/news na saída do log:

    Mensagem de /topic/news é mostrada

Quando essa mensagem é vista na janela de saída, o ícone de notificação também deve aparecer na área de notificação no dispositivo Android. Abra o ícone de notificação para exibir a mensagem de tópico:

A mensagem de tópico aparece como uma notificação

Se você não receber uma mensagem, tente excluir o aplicativo FCMClient no dispositivo (ou emulador) e repita as etapas acima.

Notificações em primeiro plano

Para receber notificações em aplicativos em primeiro plano, você deve implementar FirebaseMessagingServiceo . Esse serviço também é necessário para receber cargas de dados e para enviar mensagens upstream. Os exemplos a seguir ilustram como implementar um serviço que se estende FirebaseMessagingService – o aplicativo resultante poderá lidar com notificações remotas enquanto estiver sendo executado em primeiro plano.

Implementar FirebaseMessagingService

O FirebaseMessagingService serviço é responsável por receber e processar as mensagens do Firebase. Cada aplicativo deve subclassificar esse tipo e substituir o OnMessageReceived para processar uma mensagem de entrada. Quando um aplicativo está em primeiro plano, o OnMessageReceived retorno de chamada sempre manipulará a mensagem.

Observação

Os aplicativos têm apenas 10 segundos para lidar com uma mensagem de nuvem do Firebase recebida. Qualquer trabalho que leve mais tempo do que isso deve ser agendado para execução em segundo plano usando uma biblioteca, como o Agendador de Tarefas do Android ou o Dispatcher do Firebase.

Adicione um novo arquivo chamado MyFirebaseMessagingService.cs e substitua seu código de modelo pelo seguinte:

using System;
using Android.App;
using Android.Content;
using Android.Media;
using Android.Util;
using Firebase.Messaging;

namespace FCMClient
{
    [Service]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    public class MyFirebaseMessagingService : FirebaseMessagingService
    {
        const string TAG = "MyFirebaseMsgService";
        public override void OnMessageReceived(RemoteMessage message)
        {
            Log.Debug(TAG, "From: " + message.From);
            Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
        }
    }
}

Observe que o filtro de intenção deve ser declarado MESSAGING_EVENT para que novas mensagens do FCM sejam direcionadas para MyFirebaseMessagingService:

[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]

Quando o aplicativo cliente recebe uma mensagem do FCM, OnMessageReceived extrai o conteúdo da mensagem do objeto transmitido RemoteMessage chamando seu GetNotification método. Em seguida, ele registra o conteúdo da mensagem para que ele possa ser exibido na janela de saída do IDE:

var body = message.GetNotification().Body;
Log.Debug(TAG, "Notification Message Body: " + body);

Observação

Se você definir pontos de interrupção no FirebaseMessagingService, sua sessão de depuração poderá ou não atingir esses pontos de interrupção devido à forma como o FCM entrega mensagens.

Envie outra mensagem

Desinstale o aplicativo, recompile-o, execute-o novamente e siga estas etapas para enviar outra mensagem:

  1. No Console do Firebase, clique em NOVA MENSAGEM.

  2. Na página Redigir mensagem , insira o texto da mensagem e selecione Dispositivo único.

  3. Copie a cadeia de caracteres do token da janela de saída do IDE e cole-a no campo de token de registro do FCM do Console do Firebase como antes.

  4. Verifique se o aplicativo está sendo executado em primeiro plano e clique em ENVIAR MENSAGEM no Console do Firebase:

    Enviando outra mensagem do Console

  5. Quando a caixa de diálogo Revisar mensagem for exibida, clique em ENVIAR.

  6. A mensagem de entrada é registrada na janela de saída do IDE:

    Corpo da mensagem impresso na janela de saída

Adicionar um remetente de notificação local

Neste exemplo restante, a mensagem FCM de entrada será convertida em uma notificação local que é iniciada enquanto o aplicativo está sendo executado em primeiro plano. Edite MyFirebaseMessageService.cs e adicione as seguintes using instruções:

using FCMClient;
using System.Collections.Generic;

Adicione o seguinte método a MyFirebaseMessagingService:

void SendNotification(string messageBody, IDictionary<string, string> data)
{
    var intent = new Intent(this, typeof(MainActivity));
    intent.AddFlags(ActivityFlags.ClearTop);
    foreach (var key in data.Keys)
    {
        intent.PutExtra(key, data[key]);
    }

    var pendingIntent = PendingIntent.GetActivity(this,
                                                  MainActivity.NOTIFICATION_ID,
                                                  intent,
                                                  PendingIntentFlags.OneShot);

    var notificationBuilder = new  NotificationCompat.Builder(this, MainActivity.CHANNEL_ID)
                              .SetSmallIcon(Resource.Drawable.ic_stat_ic_notification)
                              .SetContentTitle("FCM Message")
                              .SetContentText(messageBody)
                              .SetAutoCancel(true)
                              .SetContentIntent(pendingIntent);

    var notificationManager = NotificationManagerCompat.From(this);
    notificationManager.Notify(MainActivity.NOTIFICATION_ID, notificationBuilder.Build());
}

Para distinguir essa notificação das notificações em segundo plano, esse código marca as notificações com um ícone diferente do ícone do aplicativo. Adicione o arquivo ic_stat_ic_notification.png a Resources/drawable e inclua-o no projeto FCMClient.

O SendNotification método é usado NotificationCompat.Builder para criar a notificação e NotificationManagerCompat é usado para iniciar a notificação. A notificação contém um PendingIntent que permitirá ao usuário abrir o aplicativo e exibir o conteúdo da cadeia de caracteres passada para messageBodyo . Para obter mais informações sobre NotificationCompat.Buildero , consulte Notificações locais.

Chame o SendNotification método no final do OnMessageReceived método:

public override void OnMessageReceived(RemoteMessage message)
{
    Log.Debug(TAG, "From: " + message.From);

    var body = message.GetNotification().Body;
    Log.Debug(TAG, "Notification Message Body: " + body);
    SendNotification(body, message.Data);
}

Como resultado dessas alterações, SendNotification será executado sempre que uma notificação for recebida enquanto o aplicativo estiver em primeiro plano, e a notificação aparecerá na área de notificação.

Quando um aplicativo está em segundo plano, a carga da mensagem determinará como a mensagem é tratada:

  • Notificação – as mensagens serão enviadas para a bandeja do sistema. Uma notificação local aparecerá lá. Quando o usuário tocar na notificação, o aplicativo será iniciado.
  • Dados – as mensagens serão tratadas pela OnMessageReceived.
  • Ambos – as mensagens que têm uma notificação e carga de dados serão entregues na bandeja do sistema. Quando o aplicativo for iniciado, a carga de dados aparecerá no Extras do Intent que foi usado para iniciar o aplicativo.

Neste exemplo, se o aplicativo estiver em segundo plano, SendNotification será executado se a mensagem tiver uma carga de dados. Caso contrário, uma notificação em segundo plano (ilustrada anteriormente neste passo a passo) será iniciada.

Enviar a última mensagem

Desinstale o aplicativo, recompile-o, execute-o novamente e use as seguintes etapas para enviar a última mensagem:

  1. No Console do Firebase, clique em NOVA MENSAGEM.

  2. Na página Redigir mensagem , insira o texto da mensagem e selecione Dispositivo único.

  3. Copie a cadeia de caracteres do token da janela de saída do IDE e cole-a no campo de token de registro do FCM do Console do Firebase como antes.

  4. Verifique se o aplicativo está sendo executado em primeiro plano e clique em ENVIAR MENSAGEM no Console do Firebase:

    Enviando a mensagem de primeiro plano

Desta vez, a mensagem que foi registrada na janela de saída também é empacotada em uma nova notificação – o ícone de notificação aparece na bandeja de notificação enquanto o aplicativo está sendo executado em primeiro plano:

Ícone de notificação para mensagem de primeiro plano

Ao abrir a notificação, você verá a última mensagem enviada da GUI de Notificações do Console do Firebase:

Notificação de primeiro plano mostrada com ícone de primeiro plano

Desconexão do FCM

Para cancelar a assinatura de um tópico, chame o método UnsubscribeFromTopic na classe FirebaseMessaging. Por exemplo, para cancelar a assinatura do tópico de notícias inscrito anteriormente, um botão Cancelar inscrição pode ser adicionado ao layout com o seguinte código de manipulador:

var unSubscribeButton = FindViewById<Button>(Resource.Id.unsubscribeButton);
unSubscribeButton.Click += delegate {
    FirebaseMessaging.Instance.UnsubscribeFromTopic("news");
    Log.Debug(TAG, "Unsubscribed from remote notifications");
};

Para cancelar completamente o registro do dispositivo do FCM, exclua o ID da instância chamando o método DeleteInstanceId na classe FirebaseInstanceId . Por exemplo:

FirebaseInstanceId.Instance.DeleteInstanceId();

Essa chamada de método exclui o ID da instância e os dados associados a ela. Como resultado, o envio periódico de dados do FCM para o dispositivo é interrompido.

Solução de problemas

A seguir descrevemos problemas e soluções alternativas que podem surgir ao usar o Firebase Cloud Messaging com o Xamarin.Android.

FirebaseApp não foi inicializado

Em alguns casos, você verá essa mensagem de erro:

Java.Lang.IllegalStateException: Default FirebaseApp is not initialized in this process
Make sure to call FirebaseApp.initializeApp(Context) first.

Esse é um problema conhecido que você pode contornar limpando a solução e reconstruindo o projeto (Build > Clean Solution, Build > Rebuild Solution).

Resumo

Este passo a passo detalhou as etapas para implementar notificações remotas do Firebase Cloud Messaging em um aplicativo Xamarin.Android. Ele descreveu como instalar os pacotes necessários para comunicações do FCM e explicou como configurar o Manifesto do Android para acesso aos servidores FCM. Ele forneceu um código de exemplo que ilustra como verificar a presença do Google Play Services. Ele demonstrou como implementar um serviço de escuta de ID de instância que negocia com o FCM um token de registro e explicou como esse código cria notificações em segundo plano enquanto o aplicativo está em segundo plano. Ele explicou como assinar mensagens de tópico e forneceu um exemplo de implementação de um serviço de escuta de mensagens que é usado para receber e exibir notificações remotas enquanto o aplicativo está sendo executado em primeiro plano.