Remote Notifications with Firebase Cloud Messaging (Notifiche remote con Firebase Cloud Messaging)

Questa procedura dettagliata fornisce una spiegazione dettagliata di come usare Firebase Cloud Messaging per implementare notifiche remote (dette anche notifiche push) in un'applicazione Xamarin.Android. Illustra come implementare le varie classi necessarie per le comunicazioni con Firebase Cloud Messaging (FCM), fornisce esempi di come configurare il manifesto Android per l'accesso a FCM e illustra la messaggistica downstream usando la console Firebase.

Panoramica delle notifiche FCM

In questa procedura dettagliata verrà creata un'app di base denominata FCMClient per illustrare le nozioni di base della messaggistica FCM. FCMClient verifica la presenza di Google Play Services, riceve i token di registrazione da FCM, visualizza le notifiche remote inviate dalla Console Firebase e sottoscrive i messaggi degli argomenti:

Example screenshot of app

Verranno esaminate le aree di argomento seguenti:

  1. Notifiche in background

  2. Messaggi dell'argomento

  3. Notifiche in primo piano

Durante questa procedura dettagliata, si aggiungeranno in modo incrementale funzionalità a FCMClient ed eseguirla in un dispositivo o in un emulatore per comprendere come interagisce con FCM. Si userà la registrazione per verificare le transazioni delle app attive con i server FCM e si noterà come le notifiche vengono generate dai messaggi FCM immessi nell'interfaccia utente grafica delle notifiche di Firebase Console.

Requisiti

Sarà utile acquisire familiarità con i diversi tipi di messaggi che possono essere inviati da Firebase Cloud Messaging. Il payload del messaggio determinerà il modo in cui un'app client riceverà ed elaborerà il messaggio.

Prima di procedere con questa procedura dettagliata, è necessario acquisire le credenziali necessarie per usare i server FCM di Google; questo processo è illustrato in Firebase Cloud Messaging. In particolare, è necessario scaricare il file di google-services.json da usare con il codice di esempio presentato in questa procedura dettagliata. Se non è ancora stato creato un progetto in Firebase Console (o se il file di google-services.json non è ancora stato scaricato), vedere Firebase Cloud Messaging.

Per eseguire l'app di esempio, è necessario un dispositivo di test Android o un emulatore compatibile con Firebase. Firebase Cloud Messaging supporta i client in esecuzione in Android 4.0 o versione successiva e anche questi dispositivi devono avere l'app Google Play Store installata (è necessaria l'app Google Play Services 9.2.1 o versione successiva). Se non hai ancora installato l'app Google Play Store sul tuo dispositivo, visita il sito Web di Google Play per scaricarla e installarla. In alternativa, puoi usare l'emulatore Android SDK con Google Play Services installato invece di un dispositivo di test (non devi installare Google Play Store se usi l'emulatore android SDK).

Avviare un progetto di app

Per iniziare, creare un nuovo progetto Xamarin.Android vuoto denominato FCMClient. Se non si ha familiarità con la creazione di progetti Xamarin.Android, vedere Hello, Android. Dopo aver creato la nuova app, il passaggio successivo consiste nell'impostare il nome del pacchetto e installare diversi pacchetti NuGet che verranno usati per la comunicazione con FCM.

Impostare il nome del pacchetto

In Firebase Cloud Messaging è stato specificato un nome di pacchetto per l'app abilitata per FCM. Questo nome del pacchetto funge anche da ID applicazione associato alla chiave API. Configurare l'app per l'uso del nome del pacchetto:

  1. Aprire le proprietà per il progetto FCMClient .

  2. Nella pagina Manifesto Android impostare il nome del pacchetto.

Nell'esempio seguente il nome del pacchetto è impostato su com.xamarin.fcmexample:

Setting the package name

Durante l'aggiornamento del manifesto Android, verificare anche che l'autorizzazione Internet sia abilitata.

Importante

L'app client non sarà in grado di ricevere un token di registrazione da FCM se questo nome del pacchetto non corrisponde esattamente al nome del pacchetto immesso nella Console Firebase.

Aggiungere il pacchetto di base di Xamarin Google Play Services

Poiché Firebase Cloud Messaging dipende da Google Play Services, il pacchetto NuGet Xamarin Google Play Services - Base NuGet deve essere aggiunto al progetto Xamarin.Android. Sarà necessaria la versione 29.0.0.2 o successiva.

  1. In Visual Studio fare clic con il pulsante destro del mouse su Riferimenti > gestisci pacchetti NuGet ....

  2. Fare clic sulla scheda Sfoglia e cercare Xamarin.GooglePlayServices.Base.

  3. Installare questo pacchetto nel progetto FCMClient :

    Installing Google Play Services Base

Se viene visualizzato un errore durante l'installazione di NuGet, chiudere il progetto FCMClient , aprirlo di nuovo e ripetere l'installazione di NuGet.

Quando si installa Xamarin.GooglePlayServices.Base, vengono installate anche tutte le dipendenze necessarie. Modificare MainActivity.cs e aggiungere l'istruzione seguente using :

using Android.Gms.Common;

Questa istruzione rende la classe in Xamarin.GooglePlayServices.Base disponibile per il GoogleApiAvailability codice FCMClient. GoogleApiAvailability viene usato per verificare la presenza di Google Play Services.

Aggiungere il pacchetto di messaggistica di Xamarin Firebase

Per ricevere messaggi da FCM, è necessario aggiungere il pacchetto NuGet Xamarin Firebase - Messaging al progetto dell'app. Senza questo pacchetto, un'applicazione Android non può ricevere messaggi dai server FCM.

  1. In Visual Studio fare clic con il pulsante destro del mouse su Riferimenti > gestisci pacchetti NuGet ....

  2. Cercare Xamarin.Firebase.Messaging.

  3. Installare questo pacchetto nel progetto FCMClient :

    Installing Xamarin Firebase Messaging

Quando si installa Xamarin.Firebase.Messaging, vengono installate anche tutte le dipendenze necessarie.

Modificare quindi MainActivity.cs e aggiungere le istruzioni seguenti using :

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

Le prime due istruzioni rendono disponibili i tipi nel pacchetto NuGet Xamarin.Firebase.Messaging per il codice FCMClient . Android.Util aggiunge funzionalità di registrazione che verranno usate per osservare le transazioni con FMS.

Aggiungere il file JSON di Google Services

Il passaggio successivo consiste nell'aggiungere il file google-services.json alla directory radice del progetto:

  1. Copiare google-services.json nella cartella del progetto.

  2. Aggiungere google-services.json al progetto dell'app (fare clic su Mostra tutti i file nel Esplora soluzioni, fare clic con il pulsante destro del mouse google-services.json e quindi scegliere Includi in progetto).

  3. Selezionare google-services.json nella finestra Esplora soluzioni.

  4. Nel riquadro Proprietà impostare Azionedi compilazione su GoogleServicesJson:

    Setting the build action to GoogleServicesJson

    Nota

    Se l'azione di compilazione GoogleServicesJson non viene visualizzata, salvare e chiudere la soluzione, riaprirla.

Quando google-services.json viene aggiunto al progetto (e viene impostata l'azione di compilazione GoogleServicesJson), il processo di compilazione estrae l'ID client e la chiave API e quindi aggiunge queste credenziali al AndroidManifest.xml unito/generato che risiede in obj/Debug/android/AndroidManifest.xml. Questo processo di unione aggiunge automaticamente tutte le autorizzazioni e altri elementi FCM necessari per la connessione ai server FCM.

Verificare la presenza di Google Play Services e creare un canale di notifica

Google consiglia alle app Android di verificare la presenza dell'APK di Google Play Services prima di accedere alle funzionalità di Google Play Services (per altre informazioni, vedere Controllare i servizi Google Play).

Verrà creato un layout iniziale per l'interfaccia utente dell'app. Modificare Resources/layout/Main.axml e sostituirlo con il codice XML seguente:

<?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>

Verrà TextView usato per visualizzare i messaggi che indicano se Google Play Services è installato. Salvare le modifiche apportate a Main.axml.

Modificare MainActivity.cs e aggiungere le variabili di istanza seguenti alla 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;

Le variabili CHANNEL_ID e NOTIFICATION_ID verranno usate nel metodo CreateNotificationChannel che verrà aggiunto a MainActivity più avanti in questa procedura dettagliata.

Nell'esempio seguente il OnCreate metodo verificherà che Google Play Services sia disponibile prima che l'app tenti di usare i servizi FCM. Aggiungere il metodo seguente alla 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;
    }
}

Questo codice controlla il dispositivo per verificare se è installato l'APK di Google Play Services. Se non è installato, viene visualizzato un messaggio in TextBox che indica all'utente di scaricare un APK da Google Play Store (o di abilitarlo nelle impostazioni di sistema del dispositivo).

Le app in esecuzione in Android 8.0 (livello API 26) o versioni successive devono creare un canale di notifica per la pubblicazione delle notifiche. Aggiungere il metodo seguente alla MainActivity classe che creerà il canale di notifica (se necessario):

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);
}

Sostituire il metodo OnCreate con il codice seguente:

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

    IsPlayServicesAvailable ();

    CreateNotificationChannel();
}

IsPlayServicesAvailable viene chiamato alla fine di OnCreate in modo che il controllo di Google Play Services venga eseguito ogni volta che l'app viene avviata. Il metodo CreateNotificationChannel viene chiamato per assicurarsi che esista un canale di notifica per i dispositivi che eseguono Android 8 o versione successiva. Se l'app ha un OnResume metodo, deve chiamare IsPlayServicesAvailable anche da OnResume . Ricompilare ed eseguire completamente l'app. Se tutto è configurato correttamente, verrà visualizzata una schermata simile alla schermata seguente:

App indicates that Google Play Services is available

Se non si ottiene questo risultato, verificare che l'APK di Google Play Services sia installato nel dispositivo (per altre informazioni, vedere Configurazione di Google Play Services). Verificare anche di aver aggiunto il pacchetto Xamarin.Google.Play.Services.Base al progetto FCMClient , come illustrato in precedenza.

Aggiungere il ricevitore id istanza

Il passaggio successivo consiste nell'aggiungere un servizio che si estende FirebaseInstanceIdService per gestire la creazione, la rotazione e l'aggiornamento dei token di registrazione Firebase. Il FirebaseInstanceIdService servizio è necessario affinché FCM sia in grado di inviare messaggi al dispositivo. Quando il FirebaseInstanceIdService servizio viene aggiunto all'app client, l'app riceverà automaticamente i messaggi FCM e li visualizzerà come notifiche ogni volta che l'app è in background.

Dichiarare il ricevitore nel manifesto Android

Modificare AndroidManifest.xml e inserire gli elementi seguenti <receiver> nella <application> sezione :

<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>

Questo codice XML esegue le operazioni seguenti:

  • Dichiara un'implementazione FirebaseInstanceIdReceiver che fornisce un identificatore univoco per ogni istanza dell'app. Questo ricevitore autentica e autorizza anche le azioni.

  • Dichiara un'implementazione interna FirebaseInstanceIdInternalReceiver usata per avviare i servizi in modo sicuro.

  • L'ID app viene archiviato nel file google-services.json aggiunto al progetto. Le associazioni Firebase di Xamarin.Android sostituiranno il token ${applicationId} con l'ID app. Nessun codice aggiuntivo è richiesto dall'app client per fornire l'ID app.

FirebaseInstanceIdReceiver è un oggetto WakefulBroadcastReceiver che riceve FirebaseInstanceId e FirebaseMessaging gli eventi e li recapita alla classe derivata da FirebaseInstanceIdService.

Implementare il servizio ID istanza firebase

Il lavoro di registrazione dell'applicazione con FCM viene gestito dal servizio personalizzato fornito dall'utente FirebaseInstanceIdService . FirebaseInstanceIdService esegue i passaggi seguenti:

  1. Usa l'API ID istanza per generare token di sicurezza che autorizzano l'app client ad accedere a FCM e al server app. In cambio, l'app ottiene un token di registrazione da FCM.

  2. Inoltra il token di registrazione al server app se il server app lo richiede.

Aggiungere un nuovo file denominato MyFirebaseIIDService.cs e sostituirlo con il codice del modello seguente:

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.
        }
    }
}

Questo servizio implementa un OnTokenRefresh metodo richiamato quando il token di registrazione viene inizialmente creato o modificato. Quando OnTokenRefresh viene eseguito, recupera il token più recente dalla FirebaseInstanceId.Instance.Token proprietà , che viene aggiornata in modo asincrono da FCM. In questo esempio il token aggiornato viene registrato in modo che possa essere visualizzato nella finestra di output:

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

OnTokenRefresh viene richiamato raramente: viene usato per aggiornare il token nelle circostanze seguenti:

  • Quando l'app viene installata o disinstallata.

  • Quando l'utente elimina i dati dell'app.

  • Quando l'app cancella l'ID istanza.

  • Quando la sicurezza del token è stata compromessa.

In base alla documentazione relativa all'ID istanza di Google, il servizio ID istanza FCM richiederà che l'app aggiorni periodicamente il token (in genere ogni 6 mesi).

OnTokenRefresh chiama SendRegistrationToAppServer anche per associare il token di registrazione dell'utente all'account lato server (se presente) gestito dall'applicazione:

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

Poiché questa implementazione dipende dalla progettazione del server app, in questo esempio viene fornito un corpo del metodo vuoto. Se il server app richiede informazioni di registrazione FCM, modificare SendRegistrationToAppServer per associare il token ID istanza FCM dell'utente a qualsiasi account lato server gestito dall'app. Si noti che il token è opaco per l'app client.

Quando un token viene inviato al server app, SendRegistrationToAppServer deve mantenere un valore booleano per indicare se il token è stato inviato al server. Se questo valore booleano è false, SendRegistrationToAppServer invia il token al server app. In caso contrario, il token è già stato inviato al server app in una chiamata precedente. In alcuni casi,ad esempio questo FCMClient esempio, il server app non necessita del token. Di conseguenza, questo metodo non è necessario per questo esempio.

Implementare il codice dell'app client

Ora che i servizi ricevitori sono disponibili, è possibile scrivere il codice dell'app client per sfruttare questi servizi. Nelle sezioni seguenti viene aggiunto un pulsante all'interfaccia utente per registrare il token di registrazione (detto anche token ID istanza) e viene aggiunto altro codice per MainActivity visualizzare Intent le informazioni all'avvio dell'app da una notifica:

Log Token button added to app screen

Token di log

Il codice aggiunto in questo passaggio è destinato solo a scopi dimostrativi: un'app client di produzione non deve registrare i token di registrazione. Modificare Resources/layout/Main.axml e aggiungere la dichiarazione seguente Button immediatamente dopo l'elemento TextView :

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

Aggiungere il codice seguente alla fine del metodo MainActivity.OnCreate:

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

Questo codice registra il token corrente nella finestra di output quando viene toccato il pulsante Token di log.

Gestire le finalità di notifica

Quando l'utente tocca una notifica inviata da FCMClient, tutti i dati che accompagnano tale messaggio di notifica vengono resi disponibili in Intent extra. Modificare MainActivity.cs e aggiungere il codice seguente all'inizio del OnCreate metodo (prima della chiamata a 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);
    }
}

L'utilità di avvio Intent dell'app viene attivata quando l'utente tocca il messaggio di notifica, quindi questo codice logicherà tutti i dati correlati nella Intent finestra di output. Se è necessario attivare un elemento diverso Intent , il click_action campo del messaggio di notifica deve essere impostato su tale Intent campo (l'utilità di avvio Intent viene usata quando non viene specificato alcun click_action valore).

Notifiche in background

Compilare ed eseguire l'app FCMClient . Viene visualizzato il pulsante Token di log:

Log Token button is displayed

Toccare il pulsante Log Token (Token di log). Nella finestra di output dell'IDE deve essere visualizzato un messaggio simile al seguente:

Instance ID token displayed in Output window

La stringa lunga etichettata con token è il token ID istanza che verrà incollato nella console firebase. Selezionare e copiare questa stringa negli Appunti. Se non viene visualizzato un token ID istanza, aggiungere la riga seguente all'inizio del OnCreate metodo per verificare che google-services.json sia stato analizzato correttamente:

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

Il google_app_id valore registrato nella finestra di output deve corrispondere al mobilesdk_app_id valore registrato in google-services.json. L'oggetto Resource.String.google_app_id viene generato da msbuild durante l'elaborazione google-services.json.

Inviare un messaggio

Accedere alla console firebase, selezionare il progetto, fare clic su Notifiche e fare clic su edizione Standard ND IL PRIMO MESSAGGIO:

Send Your First Message button

Nella pagina Compose message (Componi messaggio) immettere il testo del messaggio e selezionare Single device (Dispositivo singolo). Copiare il token ID istanza dalla finestra di output dell'IDE e incollarlo nel campo token di registrazione FCM della console Firebase:

Compose message dialog

Nel dispositivo Android (o emulatore) eseguire lo sfondo dell'app toccando il pulsante Panoramica di Android e toccando la schermata iniziale. Quando il dispositivo è pronto, fare clic su edizione Standard ND MESSAGE nella console firebase:

Send message button

Quando viene visualizzata la finestra di dialogo Verifica messaggio, fare clic su edizione Standard ND. L'icona di notifica dovrebbe essere visualizzata nell'area di notifica del dispositivo (o emulatore):

Notification icon is shown

Aprire l'icona di notifica per visualizzare il messaggio. Il messaggio di notifica deve essere esattamente ciò che è stato digitato nel campo Testo messaggio della console Firebase:

Notification message is displayed on the device

Toccare l'icona di notifica per avviare l'app FCMClient . Gli Intent extra inviati a FCMClient sono elencati nella finestra di output dell'IDE:

Intent extras lists from key, message ID, and collapse key

In questo esempio, la chiave from viene impostata sul numero di progetto Firebase dell'app (in questo esempio 41590732, ) e il collapse_key viene impostato sul nome del pacchetto (com.xamarin.fcmexample). Se non si riceve un messaggio, provare a eliminare l'app FCMClient nel dispositivo (o nell'emulatore) e ripetere i passaggi precedenti.

Nota

Se si chiude forzatamente l'app, FCM interromperà il recapito delle notifiche. Android impedisce le trasmissioni del servizio in background da avviare inavvertitamente o inutilmente i componenti delle applicazioni arrestate. Per altre informazioni su questo comportamento, vedere Avviare i controlli nelle applicazioni arrestate. Per questo motivo, è necessario disinstallare manualmente l'app ogni volta che viene eseguita e arrestarla da una sessione di debug. In questo modo FCM forza la generazione di un nuovo token in modo che i messaggi continuino a essere ricevuti.

Aggiungere un'icona di notifica predefinita personalizzata

Nell'esempio precedente l'icona di notifica è impostata sull'icona dell'applicazione. Il codice XML seguente configura un'icona predefinita personalizzata per le notifiche. Android visualizza questa icona predefinita personalizzata per tutti i messaggi di notifica in cui l'icona di notifica non è impostata in modo esplicito.

Per aggiungere un'icona di notifica predefinita personalizzata, aggiungere l'icona alla directory Resources/drawable , modificare AndroidManifest.xml e inserire l'elemento seguente <meta-data> nella <application> sezione :

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

In questo esempio, l'icona di notifica che risiede in Risorse/drawable/ic_stat_ic_notification.png verrà usata come icona di notifica predefinita personalizzata. Se un'icona predefinita personalizzata non è configurata in AndroidManifest.xml e nessuna icona è impostata nel payload della notifica, Android usa l'icona dell'applicazione come icona di notifica (come illustrato nello screenshot dell'icona di notifica precedente).

Gestire i messaggi degli argomenti

Il codice scritto finora gestisce i token di registrazione e aggiunge funzionalità di notifica remota all'app. Nell'esempio seguente viene aggiunto il codice in ascolto dei messaggi di argomento e li inoltra all'utente come notifiche remote. I messaggi dell'argomento sono messaggi FCM inviati a uno o più dispositivi che sottoscrivono un argomento specifico. Per altre informazioni sui messaggi di argomento, vedere Messaggistica degli argomenti.

Sottoscrivere un argomento

Modificare Resources/layout/Main.axml e aggiungere la dichiarazione seguente Button immediatamente dopo l'elemento precedente 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" />

Questo codice XML aggiunge un pulsante Subscribe to Notification al layout. Modificare MainActivity.cs e aggiungere il codice seguente alla fine del OnCreate metodo:

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

Questo codice individua il pulsante Sottoscrivi notifica nel layout e assegna il relativo gestore clic al codice che chiama FirebaseMessaging.Instance.SubscribeToTopic, passando l'argomento sottoscritto, le notizie. Quando l'utente tocca il pulsante Sottoscrivi , l'app sottoscrive l'argomento delle notizie . Nella sezione seguente verrà inviato un messaggio di argomento di notizie dall'interfaccia utente grafica delle notifiche della console firebase.

Inviare un messaggio di argomento

Disinstallare l'app, ricompilarla ed eseguirla di nuovo. Fare clic sul pulsante Sottoscrivi notifiche :

Subscribe to Notifications button

Se l'app è stata sottoscritta correttamente, nella finestra di output dell'IDE verrà visualizzata la sincronizzazione degli argomenti completata:

Output window shows topic sync succeeded message

Per inviare un messaggio di argomento, seguire questa procedura:

  1. Nella console Firebase fare clic su NUOVO MESSAGGIO.

  2. Nella pagina Componi messaggio immettere il testo del messaggio e selezionare Argomento.

  3. Nel menu a discesa Argomento selezionare l'argomento predefinito notizie:

    Selecting the news topic

  4. Nel dispositivo Android (o emulatore) eseguire lo sfondo dell'app toccando il pulsante Panoramica di Android e toccando la schermata iniziale.

  5. Quando il dispositivo è pronto, fare clic su edizione Standard ND MESSAGE nella console firebase.

  6. Controllare la finestra di output dell'IDE per visualizzare /topics/news nell'output del log:

    Message from /topic/news is shown

Quando questo messaggio viene visualizzato nella finestra di output, l'icona di notifica dovrebbe essere visualizzata anche nell'area di notifica nel dispositivo Android. Aprire l'icona di notifica per visualizzare il messaggio dell'argomento:

The topic message appears as a notification

Se non si riceve un messaggio, provare a eliminare l'app FCMClient nel dispositivo (o nell'emulatore) e ripetere i passaggi precedenti.

Notifiche in primo piano

Per ricevere notifiche nelle app in primo piano, è necessario implementare FirebaseMessagingService. Questo servizio è necessario anche per ricevere payload di dati e per l'invio di messaggi upstream. Gli esempi seguenti illustrano come implementare un servizio che si estende FirebaseMessagingService : l'app risultante sarà in grado di gestire le notifiche remote mentre è in esecuzione in primo piano.

Implementare FirebaseMessagingService

Il FirebaseMessagingService servizio è responsabile della ricezione e dell'elaborazione dei messaggi da Firebase. Ogni app deve sottoclassare questo tipo ed eseguire l'override di OnMessageReceived per elaborare un messaggio in arrivo. Quando un'app è in primo piano, il OnMessageReceived callback gestirà sempre il messaggio.

Nota

Le app hanno solo 10 secondi in cui gestire un messaggio cloud Firebase in ingresso. Qualsiasi lavoro che richiede più tempo di questo deve essere pianificato per l'esecuzione in background usando una libreria, ad esempio l'Utilità di pianificazione processi Android o firebase Job Dispatcher.

Aggiungere un nuovo file denominato MyFirebaseMessagingService.cs e sostituirlo con il codice del modello seguente:

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);
        }
    }
}

Si noti che il MESSAGING_EVENT filtro finalità deve essere dichiarato in modo che i nuovi messaggi FCM vengano indirizzati a MyFirebaseMessagingService:

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

Quando l'app client riceve un messaggio da FCM, OnMessageReceived estrae il contenuto del messaggio dall'oggetto passato RemoteMessage chiamando il relativo GetNotification metodo. Registra quindi il contenuto del messaggio in modo che possa essere visualizzato nella finestra di output dell'IDE:

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

Nota

Se si impostano punti di interruzione in FirebaseMessagingService, la sessione di debug potrebbe raggiungere o meno questi punti di interruzione a causa del modo in cui FCM recapita i messaggi.

Inviare un altro messaggio

Disinstallare l'app, ricompilarla, eseguirla di nuovo e seguire questa procedura per inviare un altro messaggio:

  1. Nella console Firebase fare clic su NUOVO MESSAGGIO.

  2. Nella pagina Compose message (Componi messaggio) immettere il testo del messaggio e selezionare Single device (Dispositivo singolo).

  3. Copiare la stringa del token dalla finestra di output dell'IDE e incollarla nel campo token di registrazione FCM della Console Firebase come in precedenza.

  4. Assicurarsi che l'app sia in esecuzione in primo piano, quindi fare clic su edizione Standard ND MESSAGE nella console firebase:

    Sending another message from the Console

  5. Quando viene visualizzata la finestra di dialogo Verifica messaggio, fare clic su edizione Standard ND.

  6. Il messaggio in arrivo viene registrato nella finestra di output dell'IDE:

    Message body printed to output window

Aggiungere un mittente di notifica locale

In questo esempio rimanente, il messaggio FCM in arrivo verrà convertito in una notifica locale avviata mentre l'app è in esecuzione in primo piano. Modificare MyFirebaseMessageService.cs e aggiungere le istruzioni seguenti using :

using FCMClient;
using System.Collections.Generic;

Aggiungere il metodo seguente 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());
}

Per distinguere questa notifica dalle notifiche in background, questo codice contrassegna le notifiche con un'icona diversa dall'icona dell'applicazione. Aggiungere il file ic_stat_ic_notification.png a Resources/drawable e includerlo nel progetto FCMClient.

Il SendNotification metodo usa NotificationCompat.Builder per creare la notifica e NotificationManagerCompat viene usato per avviare la notifica. La notifica contiene un oggetto PendingIntent che consentirà all'utente di aprire l'app e visualizzare il contenuto della stringa passata in messageBody. Per altre informazioni su NotificationCompat.Builder, vedere Notifiche locali.

Chiamare il SendNotification metodo alla fine del OnMessageReceived metodo :

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);
}

In seguito a queste modifiche, SendNotification verrà eseguito ogni volta che viene ricevuta una notifica mentre l'app è in primo piano e la notifica verrà visualizzata nell'area di notifica.

Quando un'app è in background, il payload del messaggio determinerà come viene gestito il messaggio:

  • Notifica : i messaggi verranno inviati all'area di notifica. Verrà visualizzata una notifica locale. Quando l'utente tocca la notifica che verrà avviata dall'app.
  • Dati : i messaggi verranno gestiti da OnMessageReceived.
  • Entrambi i messaggi con una notifica e un payload di dati verranno recapitati all'area di notifica. All'avvio dell'app, il payload dei dati verrà visualizzato nell'oggetto Extras dell'oggetto Intent usato per avviare l'app.

In questo esempio, se l'app è in background, SendNotification verrà eseguita se il messaggio ha un payload di dati. In caso contrario, verrà avviata una notifica in background (illustrata in precedenza in questa procedura dettagliata).

Inviare l'ultimo messaggio

Disinstallare l'app, ricompilarla, eseguirla di nuovo, quindi seguire questa procedura per inviare l'ultimo messaggio:

  1. Nella console Firebase fare clic su NUOVO MESSAGGIO.

  2. Nella pagina Compose message (Componi messaggio) immettere il testo del messaggio e selezionare Single device (Dispositivo singolo).

  3. Copiare la stringa del token dalla finestra di output dell'IDE e incollarla nel campo token di registrazione FCM della Console Firebase come in precedenza.

  4. Assicurarsi che l'app sia in esecuzione in primo piano, quindi fare clic su edizione Standard ND MESSAGE nella console firebase:

    Sending the foreground message

Questa volta, il messaggio registrato nella finestra di output viene incluso anche in una nuova notifica. L'icona di notifica viene visualizzata nell'area di notifica mentre l'app è in esecuzione in primo piano:

Notification icon for foreground message

Quando si apre la notifica, verrà visualizzato l'ultimo messaggio inviato dall'interfaccia utente grafica delle notifiche della console firebase:

Foreground notification shown with foreground icon

Disconnessione da FCM

Per annullare la sottoscrizione a un argomento, chiamare il metodo UnsubscribeFromTopic nella classe FirebaseMessaging . Ad esempio, per annullare la sottoscrizione all'argomento notizie sottoscritto in precedenza, è possibile aggiungere un pulsante Annulla sottoscrizione al layout con il codice del gestore seguente:

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

Per annullare completamente la registrazione del dispositivo da FCM, eliminare l'ID istanza chiamando il metodo DeleteInstanceId nella classe FirebaseInstanceId . Ad esempio:

FirebaseInstanceId.Instance.DeleteInstanceId();

Questa chiamata al metodo elimina l'ID istanza e i dati associati. Di conseguenza, l'invio periodico dei dati FCM al dispositivo viene interrotto.

Risoluzione dei problemi

Di seguito vengono descritti i problemi e le soluzioni alternative che possono verificarsi quando si usa Firebase Cloud Messaging con Xamarin.Android.

FirebaseApp non è inizializzato

In alcuni casi, potrebbe essere visualizzato questo messaggio di errore:

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

Si tratta di un problema noto che è possibile risolvere pulendo la soluzione e ricompilando il progetto (Build Clean Solution, Build >> Rebuild Solution).

Riepilogo

Questa procedura dettagliata illustra in dettaglio i passaggi per l'implementazione di notifiche remote di Firebase Cloud Messaging in un'applicazione Xamarin.Android. Descrive come installare i pacchetti necessari per le comunicazioni FCM e come configurare il manifesto Android per l'accesso ai server FCM. Ha fornito codice di esempio che illustra come verificare la presenza di Google Play Services. Ha illustrato come implementare un servizio listener ID istanza che negozia con FCM per un token di registrazione e spiega come questo codice crea notifiche in background mentre l'app è in background. Ha spiegato come sottoscrivere i messaggi di argomento e ha fornito un'implementazione di esempio di un servizio listener di messaggi usato per ricevere e visualizzare notifiche remote mentre l'app è in esecuzione in primo piano.