Remote Notifications with Firebase Cloud Messaging (Notificaciones remotas con Firebase Cloud Messaging)
En este tutorial se proporciona una explicación paso a paso de cómo usar Firebase Cloud Messaging para implementar notificaciones remotas (también llamadas notificaciones push) en una aplicación de Xamarin.Android. Muestra cómo implementar las distintas clases necesarias para las comunicaciones con Firebase Cloud Messaging (FCM), proporciona ejemplos de cómo configurar el manifiesto de Android para acceder a FCM y muestra la mensajería de bajada mediante la consola de Firebase.
Introducción a las notificaciones de FCM
En este tutorial, se creará una aplicación básica denominada FCMClient para ilustrar los aspectos básicos de la mensajería FCM. FCMClient comprueba la presencia de Google Play Services, recibe tokens de registro de FCM, muestra notificaciones remotas que envía desde la consola de Firebase y se suscribe a mensajes de tema:
Se explorarán las siguientes áreas temáticas:
Notificaciones en segundo plano
Mensajes de tema
Notificaciones en primer plano
Durante este tutorial, agregará funcionalidad de forma incremental a FCMClient y la ejecutará en un dispositivo o emulador para comprender cómo interactúa con FCM. Usará el registro para presenciar transacciones de aplicaciones en directo con servidores FCM y observará cómo se generan las notificaciones a partir de mensajes FCM que escriba en la GUI de notificaciones de la consola de Firebase.
Requisitos
Le será útil familiarizarse con los diferentes tipos de mensajes que Firebase Cloud Messaging puede enviar. La carga del mensaje determinará cómo recibirá una aplicación cliente y procesará el mensaje.
Para poder continuar con este tutorial, debe adquirir las credenciales necesarias para usar los servidores FCM de Google; este proceso se explica en Firebase Cloud Messaging. En concreto, debe descargar el archivo google-services.json para usarlo con el código de ejemplo presentado en este tutorial. Si aún no ha creado un proyecto en la consola de Firebase (o si aún no ha descargado el archivo google-services.json), consulte Firebase Cloud Messaging.
Para ejecutar la aplicación de ejemplo, necesitará un dispositivo de prueba o emulador Android que sea compatible con Firebase. Firebase Cloud Messaging admite clientes que se ejecutan en Android 4.0 o posterior, y estos dispositivos también deben tener instalada la aplicación Google Play Store (se requiere Google Play Services 9.2.1 o posterior). Si aún no tiene instalada la aplicación Google Play Store en su dispositivo, visite el sitio web de Google Play para descargarla e instalarla. También puede usar el emulador de Android SDK con Google Play Services instalado en lugar de un dispositivo de prueba (no tiene que instalar Google Play Store si usa el emulador de Android SDK).
Iniciar un proyecto de aplicación
Para empezar, cree un nuevo proyecto de Xamarin.Android vacío denominado FCMClient. Si no conoce la creación de proyectos de Xamarin.Android, consulte Hello, Android. Una vez creada la nueva aplicación, el siguiente paso consiste en establecer el nombre del paquete e instalar varios paquetes NuGet que se usarán para la comunicación con FCM.
Establecer el nombre del paquete
En Firebase Cloud Messaging, especificó un nombre de paquete para la aplicación habilitada para FCM. Este nombre de paquete también actúa como el identificador de aplicación asociado a la clave de API. Configure la aplicación para que use este nombre de paquete:
Abra las propiedades del proyecto de FCMClient.
En la página Manifiesto de Android, establezca el nombre del paquete.
En el ejemplo siguiente, el nombre del paquete se establece en com.xamarin.fcmexample
:
Mientras actualiza el manifiesto de Android, compruebe también que el permiso Internet
esté habilitado.
Importante
La aplicación cliente no podrá recibir un token de registro de FCM si este nombre de paquete no coincide exactamente con el nombre del paquete que se escribió en la consola de Firebase.
Agregar el paquete base de Google Play Services de Xamarin
Dado que Firebase Cloud Messaging depende de Google Play Services, el paquete NuGet base de Xamarin Google Play Services debe agregarse al proyecto de Xamarin.Android. Necesitará la versión 29.0.0.2 o posterior.
Si recibe un error durante la instalación de NuGet, cierre el proyecto FCMClient, ábralo de nuevo y vuelva a intentar la instalación de NuGet.
Al instalar Xamarin.GooglePlayServices.Base, también se instalan todas las dependencias necesarias. Edite MainActivity.cs y agregue la siguiente instrucción using
:
using Android.Gms.Common;
Esta instrucción hace que la clase GoogleApiAvailability
de Xamarin.GooglePlayServices.Base esté disponible para el código FCMClient.
GoogleApiAvailability
se usa para comprobar la presencia de Google Play Services.
Agregar el paquete de mensajería de Xamarin Firebase
Para recibir mensajes de FCM, el paquete NuGet Xamarin Firebase: mensajería debe agregarse al proyecto de aplicación. Sin este paquete, una aplicación Android no puede recibir mensajes de servidores FCM.
Al instalar Xamarin.Firebase.Messaging, también se instalan todas las dependencias necesarias.
Luego, edite MainActivity.cs y agregue las siguientes instrucciones using
:
using Firebase.Messaging;
using Firebase.Iid;
using Android.Util;
Las dos primeras instrucciones hacen que los tipos del paquete NuGet Xamarin.Firebase.Messaging estén disponibles para el código FCMClient. Android.Util agrega funcionalidad de registro que se usará para observar transacciones con FMS.
Adición del archivo JSON de Google Services
El siguiente paso es agregar el archivo google-services.json al directorio raíz del proyecto:
Copie google-services.json en la carpeta del proyecto.
Agregue google-services.json al proyecto de aplicación (haga clic en Mostrar todos los archivos en el Explorador de soluciones, haga clic con el botón derecho en google-services.json y, a continuación, seleccione Incluir en el proyecto).
Seleccione google services.json en la ventana del Explorador de soluciones.
En el panel Propiedades, establezca la acción de compilación en GoogleServicesJson:
Nota:
Si no se muestra la acción de compilación GoogleServicesJson, guarde y cierre la solución y vuelva a abrirla.
Cuando se agrega google-services.json al proyecto (y se establece la acción de compilación de GoogleServicesJson), el proceso de compilación extrae el identificador de cliente y la clave de API y, a continuación, agrega estas credenciales al AndroidManifest.xml combinado/generado que reside en obj/Debug/android/AndroidManifest.xml. Este proceso de combinación agrega automáticamente los permisos y otros elementos FCM necesarios para la conexión a los servidores FCM.
Buscar Google Play Services y crear un canal de notificación
Google recomienda que las aplicaciones Android comprueben la presencia del APK de Google Play Services antes de acceder a las características de Google Play Services (para obtener más información, consulte Buscar servicios de Google Play).
Primero se creará un diseño inicial para la interfaz de usuario de la aplicación. Edite Resources/layout/Main.axml y reemplace su contenido por el siguiente 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>
TextView
se usará para mostrar mensajes que indiquen si Google Play Services está instalado. Guarde los cambios en Main.axml.
Edite MainActivity.cs y agregue las siguientes variables de instancia a la clase MainActivity
:
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;
Las variables CHANNEL_ID
y NOTIFICATION_ID
se usarán en el método CreateNotificationChannel
que se agregará a MainActivity
más adelante en este tutorial.
En el ejemplo siguiente, el método OnCreate
comprobará que Google Play Services está disponible antes de que la aplicación intente usar los servicios FCM.
Agregue el siguiente método a la clase 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 comprueba el dispositivo para ver si está instalado el APK de Google Play Services. Si no está instalado, se muestra un mensaje en TextBox
que indica al usuario que descargue un APK desde Google Play Store (o para habilitarlo en la configuración del sistema del dispositivo).
Las aplicaciones que se ejecutan en Android 8.0 (nivel de API 26) o superior deben crear un canal de notificación para publicar sus notificaciones. Agregue el siguiente método a la clase MainActivity
que creará el canal de notificación (si es necesario):
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);
}
Reemplace el método OnCreate
con el código siguiente:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
msgText = FindViewById<TextView> (Resource.Id.msgText);
IsPlayServicesAvailable ();
CreateNotificationChannel();
}
IsPlayServicesAvailable
se llama al final de OnCreate
para que la comprobación de Google Play Services se ejecute cada vez que se inicie la aplicación. Se llama al método CreateNotificationChannel
para asegurarse de que existe un canal de notificación para dispositivos que ejecutan Android 8 o posterior. Si la aplicación tiene un método OnResume
, también debe llamar a IsPlayServicesAvailable
desde OnResume
. Vuelva a generar completamente y ejecute la aplicación. Si todo está configurado correctamente, debería ver una pantalla similar a la siguiente captura de pantalla:
Si no obtiene este resultado, compruebe que el APK de Google Play Services está instalado en su dispositivo (para obtener más información, consulte Configurar Google Play Services). Compruebe también que ha agregado el paquete Xamarin.Google.Play.Services.Base al proyecto FCMClient como se explicó anteriormente.
Agregar el receptor de identificadores de instancia
El siguiente paso es agregar un servicio que extiende FirebaseInstanceIdService
para controlar la creación, rotación y actualización de tokens de registro de Firebase. El servicio FirebaseInstanceIdService
es necesario para que FCM pueda enviar mensajes al dispositivo. Cuando el servicio FirebaseInstanceIdService
se agrega a la aplicación cliente, la aplicación recibirá automáticamente mensajes FCM y los mostrará como notificaciones cada vez que la aplicación esté en segundo plano.
Declarar el receptor en el manifiesto de Android
Edite AndroidManifest.xml e inserte los siguientes elementos <receiver>
en la sección <application>
:
<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>
El XML hace lo siguiente:
Declara una implementación
FirebaseInstanceIdReceiver
que proporciona un identificador único para cada instancia de aplicación. Este receptor también autentica y autoriza acciones.Declara una implementación interna
FirebaseInstanceIdInternalReceiver
que se usa para iniciar los servicios de forma segura.El id. de la aplicación se almacena en el archivo google-services.json que se agregó al proyecto. Los enlaces de Firebase de Xamarin.Android reemplazarán el token
${applicationId}
por el id. de la aplicación; la aplicación cliente no requiere ningún código adicional para proporcionar el id. de la aplicación.
FirebaseInstanceIdReceiver
es un objeto WakefulBroadcastReceiver
que recibe eventos FirebaseInstanceId
y FirebaseMessaging
, y los entrega a la clase que usted deriva de FirebaseInstanceIdService
.
Implementación del servicio de id. de instancia de Firebase
El trabajo de registrar la aplicación con FCM se controla mediante el servicio personalizado FirebaseInstanceIdService
que proporcione.
FirebaseInstanceIdService
realiza las tareas siguientes:
Usa la API de id. de instancia para generar tokens de seguridad que autorizan a la aplicación cliente a acceder a FCM y al servidor de aplicaciones. A cambio, la aplicación devuelve un token de registro de FCM.
Reenvía el token de registro al servidor de aplicaciones si el servidor de aplicaciones lo requiere.
Agregue un nuevo archivo denominado MyFirebaseIIDService.cs y reemplace su código de plantilla por lo siguiente:
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.
}
}
}
Este servicio implementa un método OnTokenRefresh
que se invoca cuando se crea o cambia inicialmente el token de registro. Cuando se ejecuta OnTokenRefresh
, recupera el token más reciente de la propiedad FirebaseInstanceId.Instance.Token
(que FCM actualiza de forma asincrónica). En este ejemplo, se registra el token actualizado para que se pueda ver en la ventana de salida:
var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(TAG, "Refreshed token: " + refreshedToken);
OnTokenRefresh
se invoca con poca frecuencia: se usa para actualizar el token en las siguientes circunstancias:
Cuando la aplicación está instalada o desinstalada.
Cuando el usuario elimina los datos de la aplicación.
Cuando la aplicación borra el identificador de instancia.
Cuando se ha puesto en peligro la seguridad del token.
Según la documentación del identificador de instancia de Google, el servicio de id. de instancia de FCM solicitará que la aplicación actualice su token periódicamente (normalmente, cada 6 meses).
OnTokenRefresh
también llama a SendRegistrationToAppServer
para asociar el token de registro del usuario a la cuenta del lado servidor (si existe) que mantiene la aplicación:
void SendRegistrationToAppServer (string token)
{
// Add custom implementation here as needed.
}
Dado que esta implementación depende del diseño del servidor de aplicaciones, se proporciona un cuerpo de método vacío en este ejemplo. Si el servidor de aplicaciones requiere información de registro de FCM, modifique SendRegistrationToAppServer
para asociar el token de identificador de instancia de FCM del usuario con cualquier cuenta del lado servidor mantenida por la aplicación. (Tenga en cuenta que el token es opaco para la aplicación cliente).
Cuando se envía un token al servidor de aplicaciones, SendRegistrationToAppServer
debe mantener un valor booleano para indicar si el token se ha enviado al servidor. Si este valor booleano es false, SendRegistrationToAppServer
envía el token al servidor de aplicaciones; de lo contrario, el token ya se envió al servidor de aplicaciones en una llamada anterior. En algunos casos (como este ejemplo de FCMClient
), el servidor de aplicaciones no necesita el token; por lo tanto, este método no es necesario para este ejemplo.
Implementación del código de aplicación cliente
Ahora que los servicios receptores están en vigor, el código de la aplicación cliente se puede escribir para aprovechar estos servicios. En las secciones siguientes, se agrega un botón a la interfaz de usuario para registrar el token de registro (también denominado token de identificador de instancia) y se agrega más código a MainActivity
para ver información de Intent
cuando la aplicación se inicia desde una notificación:
Registrar tokens
El código agregado en este paso solo está pensado para fines de demostración: una aplicación cliente de producción no tendría necesidad de registrar tokens de registro. Edite Resources/layout/Main.axml y agregue la siguiente declaración Button
inmediatamente después del 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" />
Agregue el siguiente código al final del método MainActivity.OnCreate
:
var logTokenButton = FindViewById<Button>(Resource.Id.logTokenButton);
logTokenButton.Click += delegate {
Log.Debug(TAG, "InstanceID token: " + FirebaseInstanceId.Instance.Token);
};
Este código registra el token actual en la ventana de salida cuando se pulsa el botón Registrar token.
Control de intenciones de notificación
Cuando el usuario pulsa una notificación emitida desde FCMClient, los datos que acompañan a ese mensaje de notificación están disponibles en extras de Intent
. Edite MainActivity.cs y agregue el código siguiente en la parte superior del método OnCreate
(antes de la llamada 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);
}
}
El iniciador de la aplicación Intent
se desencadena cuando el usuario pulsa su mensaje de notificación, por lo que este código registrará los datos adjuntos en la ventana de salida Intent
. Si se debe activar otro Intent
, el campo del mensaje de notificación click_action
debe establecerse en ese Intent
(el iniciador Intent
se usa cuando no se especifica click_action
).
Notificaciones en segundo plano
Compile y ejecute la aplicación FCMClient. Se muestra el botón Registrar token:
Pulse el botón Registrar token. Se debe mostrar un mensaje similar al siguiente en la ventana de salida del IDE:
La cadena larga etiquetada con token es el token de identificador de instancia que pegará en la consola de Firebase: seleccione y copie esta cadena en el Portapapeles. Si no ve un token de identificador de instancia, agregue la siguiente línea a la parte superior del método OnCreate
para comprobar que google-services.json se ha analizado correctamente:
Log.Debug(TAG, "google app id: " + GetString(Resource.String.google_app_id));
El valor google_app_id
registrado en la ventana de salida debe coincidir con el valor mobilesdk_app_id
registrado en google-services.json. Msbuild genera el objeto Resource.String.google_app_id
al procesar google-services.json.
Envío de un mensaje
Inicie sesión en la consola de Firebase, seleccione el proyecto, haga clic en Notificaciones y haga clic en ENVIAR SU PRIMER MENSAJE:
En la página Redactar mensaje, escriba el texto del mensaje y seleccione Dispositivo único. Copie el token de identificador de instancia de la ventana de salida del IDE y péguelo en el campo token de registro de FCM de la consola de Firebase:
En el dispositivo (o emulador) de Android, deje en segundo plano la aplicación al pulsar el botón Información general de Android y tocar la pantalla principal. Cuando el dispositivo esté listo, haga clic en ENVIAR MENSAJE en la consola de Firebase:
Cuando se muestre el cuadro de diálogo Revisar mensaje, haga clic en ENVIAR. El icono de notificación debe aparecer en el área de notificación del dispositivo (o emulador):
Abra el icono de notificación para ver el mensaje. El mensaje de notificación debe ser exactamente lo que se ha escrito en el campo Texto del mensaje de la consola de Firebase:
Pulse el icono de notificación para iniciar la aplicación FCMClient. Los extras de Intent
enviados a FCMClient se muestran en la ventana de salida del IDE:
En este ejemplo, la clave from se establece en el número de proyecto Firebase de la aplicación (en este ejemplo, 41590732
) y collapse_key se establece en su nombre de paquete (com.xamarin.fcmexample).
Si no recibe un mensaje, intente eliminar la aplicación FCMClient en el dispositivo (o emulador) y repita los pasos anteriores.
Nota:
Si cierra la aplicación a la fuerza, FCM dejará de entregar notificaciones. Android impide que las difusiones del servicio en segundo plano inicien accidentalmente o de forma innecesaria componentes de aplicaciones detenidas. (Para obtener más información sobre este comportamiento, consulte Controles de inicio en aplicaciones detenidas). Por este motivo, es necesario desinstalar manualmente la aplicación cada vez que la ejecute y detenerla desde una sesión de depuración, lo que obliga a FCM a generar un nuevo token para que se sigan recibiendo los mensajes.
Agregar un icono de notificación predeterminado personalizado
En el ejemplo anterior, el icono de notificación se establece en el icono de la aplicación. El siguiente XML configura un icono predeterminado personalizado para las notificaciones. Android muestra este icono predeterminado personalizado para todos los mensajes de notificación en los que el icono de notificación no está establecido explícitamente.
Para agregar un icono de notificación predeterminado personalizado, agregue el icono al directorio Resources/drawable, edite AndroidManifest.xml e inserte el siguiente elemento <meta-data>
en la sección <application>
:
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification" />
En este ejemplo, el icono de notificación que reside en Resources/drawable/ic_stat_ic_notification.png se usará como icono de notificación predeterminado personalizado. Si un icono predeterminado personalizado no está configurado en AndroidManifest.xml y no se establece ningún icono en la carga de notificación, Android usa el icono de aplicación como icono de notificación (como se muestra en la captura de pantalla del icono de notificación anterior).
Control de mensajes de tema
El código escrito hasta ahora controla los tokens de registro y agrega funcionalidad de notificación remota a la aplicación. En el ejemplo siguiente se agrega código que escucha mensajes de tema y los reenvía al usuario como notificaciones remotas. Los mensajes de tema son mensajes FCM que se envían a uno o varios dispositivos que se suscriben a un tema determinado. Para obtener más información sobre los mensajes de tema, consulte Mensajería de temas.
Suscripción a un tema
Edite Resources/layout/Main.axml y agregue la siguiente declaración Button
inmediatamente después del elemento 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" />
Este XML agrega un botón Suscribirse a la notificación al diseño.
Edite MainActivity.cs y agregue el código siguiente al final del método OnCreate
:
var subscribeButton = FindViewById<Button>(Resource.Id.subscribeButton);
subscribeButton.Click += delegate {
FirebaseMessaging.Instance.SubscribeToTopic("news");
Log.Debug(TAG, "Subscribed to remote notifications");
};
Este código busca el botón Suscribirse a la notificación en el diseño y asigna su controlador de clics al código que llama a FirebaseMessaging.Instance.SubscribeToTopic
, pasando el tema suscrito Noticias. Cuando el usuario pulsa el botón Suscribirse, la aplicación se suscribe al tema de noticias. En la sección siguiente, se enviará un mensaje de tema de noticias desde la GUI de notificaciones de la consola de Firebase.
Envío de un mensaje de tema
Desinstale la aplicación, recompile y ejecútela de nuevo. Haga clic en el botón Suscribirse a las notificaciones:
Si la aplicación se ha suscrito correctamente, debería ver que la sincronización de temas se realizó correctamente en la ventana de salida del IDE:
Siga estos pasos para enviar un mensaje de tema:
En la consola de Firebase, haga clic en NUEVO MENSAJE.
En la página Redactar mensaje, escriba el texto del mensaje y seleccione Tema.
En el menú desplegable Tema, seleccione el tema integrado, noticias:
En el dispositivo (o emulador) de Android, deje en segundo plano la aplicación al pulsar el botón Información general de Android y tocar la pantalla principal.
Cuando el dispositivo esté listo, haga clic en ENVIAR MENSAJE en la consola de Firebase:
Compruebe la ventana de salida del IDE para ver /topics/news en la salida del registro:
Cuando este mensaje se vea en la ventana de salida, el icono de notificación también deberá aparecer en el área de notificación del dispositivo Android. Abra el icono de notificación para ver el mensaje de temas:
Si no recibe un mensaje, intente eliminar la aplicación FCMClient en el dispositivo (o emulador) y repita los pasos anteriores.
Notificaciones en primer plano
Para recibir notificaciones en aplicaciones en primer plano, debe implementar FirebaseMessagingService
. Este servicio también es necesario para recibir cargas de datos y para enviar mensajes ascendentes. En los ejemplos siguientes se muestra cómo implementar un servicio que extiende FirebaseMessagingService
: la aplicación resultante podrá controlar las notificaciones remotas mientras se ejecuta en primer plano.
Implementar FirebaseMessagingService
El servicio FirebaseMessagingService
es responsable de recibir y procesar los mensajes de Firebase. Cada aplicación debe hacer una subclase de este tipo e invalidar OnMessageReceived
para procesar un mensaje entrante. Cuando una aplicación está en primer plano, la devolución de llamada OnMessageReceived
siempre controlará el mensaje.
Nota:
Las aplicaciones solo tienen 10 segundos en los que controlar un mensaje entrante de Firebase Cloud. Cualquier trabajo que tarde más de esto en programarse para la ejecución en segundo plano mediante una biblioteca como Android Job Scheduler o Firebase Job Dispatcher.
Agregue un nuevo archivo denominado MyFirebaseMessagingService.cs y reemplace su código de plantilla por lo siguiente:
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);
}
}
}
Tenga en cuenta que el filtro de intención MESSAGING_EVENT
debe declararse para que los nuevos mensajes FCM se dirijan a MyFirebaseMessagingService
:
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
Cuando la aplicación cliente recibe un mensaje de FCM, OnMessageReceived
extrae el contenido del mensaje del objeto pasado RemoteMessage
llamando a su método GetNotification
. A continuación, registra el contenido del mensaje para que se pueda ver en la ventana de salida del IDE:
var body = message.GetNotification().Body;
Log.Debug(TAG, "Notification Message Body: " + body);
Nota:
Si establece puntos de interrupción en FirebaseMessagingService
, la sesión de depuración puede o no alcanzar estos puntos de interrupción debido a cómo FCM entrega mensajes.
Enviar otro mensaje
Desinstale la aplicación, recompilela, ejecútela de nuevo y siga estos pasos para enviar otro mensaje:
En la consola de Firebase, haga clic en NUEVO MENSAJE.
En la página Redactar mensaje, escriba el texto del mensaje y seleccione Dispositivo único.
Copie la cadena de token de la ventana de salida del IDE y péguela en el campo token de registro de FCM de la consola de Firebase como antes.
Asegúrese de que la aplicación se ejecuta en primer plano y, a continuación, haga clic en ENVIAR MENSAJE en la consola de Firebase:
Cuando se muestre el cuadro de diálogo Revisar mensaje, haga clic en ENVIAR.
El mensaje entrante se registra en la ventana de salida del IDE:
Agregar un remitente de notificación local
En este ejemplo restante, el mensaje FCM entrante se convertirá en una notificación local que se inicia mientras la aplicación se ejecuta en primer plano. Edite MyFirebaseMessageService.cs y agregue las siguientes instrucciones using
:
using FCMClient;
using System.Collections.Generic;
Agregue el método siguiente 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 esta notificación de las notificaciones en segundo plano, este código marca las notificaciones con un icono que difiere del icono de la aplicación. Agregue el archivo ic_stat_ic_notification.png a Resources/drawable e inclúyalo en el proyecto FCMClient.
El método SendNotification
usa NotificationCompat.Builder
para crear la notificación y NotificationManagerCompat
se usa para iniciar la notificación. La notificación contiene un PendingIntent
que permitirá al usuario abrir la aplicación y ver el contenido de la cadena pasada a messageBody
. Para obtener más información sobre NotificationCompat.Builder
, vea Notificaciones locales.
Llame al método SendNotification
al final del método OnMessageReceived
:
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 de estos cambios, SendNotification
se ejecutará cada vez que se reciba una notificación mientras la aplicación está en primer plano y la notificación aparecerá en el área de notificación.
Cuando una aplicación está en segundo plano, la carga del mensaje determinará cómo se controla el mensaje:
- Notificación: los mensajes se enviarán a la bandeja del sistema. Aparecerá una notificación local allí. Cuando el usuario pulse en la notificación, se iniciará la aplicación.
- Datos: los mensajes se controlarán mediante
OnMessageReceived
. - Ambos: los mensajes que tienen una notificación y una carga de datos se entregarán a la bandeja del sistema. Cuando se inicie la aplicación, la carga de datos aparecerá en
Extras
deIntent
que se usó para iniciar la aplicación.
En este ejemplo, si la aplicación está en segundo plano, SendNotification
se ejecutará si el mensaje tiene una carga de datos. De lo contrario, se iniciará una notificación en segundo plano (ilustrada anteriormente en este tutorial).
Enviar el último mensaje
Desinstale la aplicación, recompílela, ejecútela de nuevo y siga estos pasos para enviar el último mensaje:
En la consola de Firebase, haga clic en NUEVO MENSAJE.
En la página Redactar mensaje, escriba el texto del mensaje y seleccione Dispositivo único.
Copie la cadena de token de la ventana de salida del IDE y péguela en el campo token de registro de FCM de la consola de Firebase como antes.
Asegúrese de que la aplicación se ejecuta en primer plano y, a continuación, haga clic en ENVIAR MENSAJE en la consola de Firebase:
Esta vez, el mensaje que se registró en la ventana de salida también se empaqueta en una nueva notificación: el icono de notificación aparece en la bandeja de notificaciones mientras la aplicación se ejecuta en primer plano:
Al abrir la notificación, debería ver el último mensaje que se envió desde la GUI de notificaciones de la consola de Firebase:
Desconectando de FCM
Para cancelar la suscripción a un tema, llame al método UnsubscribeFromTopic en la clase FirebaseMessaging. Por ejemplo, para cancelar la suscripción al tema de noticias suscrito anteriormente, se podría agregar un botón Cancelar suscripción al diseño con el siguiente código de controlador:
var unSubscribeButton = FindViewById<Button>(Resource.Id.unsubscribeButton);
unSubscribeButton.Click += delegate {
FirebaseMessaging.Instance.UnsubscribeFromTopic("news");
Log.Debug(TAG, "Unsubscribed from remote notifications");
};
Para anular el registro del dispositivo de FCM por completo, elimine el identificador de instancia llamando al método DeleteInstanceId en la clase FirebaseInstanceId. Por ejemplo:
FirebaseInstanceId.Instance.DeleteInstanceId();
Esta llamada al método elimina el identificador de instancia y los datos asociados a él. Como resultado, se detiene el envío periódico de datos FCM al dispositivo.
Solución de problemas
A continuación se describen los problemas y soluciones alternativas que pueden surgir al usar Firebase Cloud Messaging con Xamarin.Android.
FirebaseApp no se inicializa
En algunos casos, es posible que vea este mensaje de error:
Java.Lang.IllegalStateException: Default FirebaseApp is not initialized in this process
Make sure to call FirebaseApp.initializeApp(Context) first.
Se trata de un problema conocido que puede solucionar limpiando la solución y recompilando el proyecto (Compilar > Limpiar solución, Compilar solución> Recompilar solución).
Resumen
En este tutorial hemos detallado los pasos para implementar notificaciones remotas de Firebase Cloud Messaging en una aplicación de Xamarin.Android. Hemos descrito cómo instalar los paquetes necesarios para las comunicaciones de FCM y explicado cómo configurar el manifiesto de Android para el acceso a los servidores FCM. Se ha proporcionado código de ejemplo que muestra cómo comprobar la presencia de Google Play Services. Hemos demostrado cómo implementar un servicio de escucha de identificador de instancia que negocia con FCM para un token de registro y explicado cómo este código crea notificaciones en segundo plano mientras la aplicación está en segundo plano. También hemos explicado cómo suscribirse a mensajes de tema y proporcionado una implementación de ejemplo de un servicio de escucha de mensajes que se usa para recibir y mostrar notificaciones remotas mientras la aplicación se ejecuta en primer plano.