En este post daré solución a un problema con el que he lidiado estos últimos días, y no es otro que la recepción de notificaciones push cuando estamos trabajando con Xamarin Forms. Hay varias alternativas para ello, pero yo me decanté por la utilización de App Center tras ver un vídeo en el que James Montemagno y Brandon Minnick hacen una rápida presentación de éste y un ejemplo sobre cómo usarlo en Android.
A continuación detallo los pasos que he seguido para tener una app capaz de recibir notificaciones push tanto en iOS como en Android.
Crear una cuenta en App Center
En mi caso he accedido con mi cuenta de Microsoft. También se podría hacer con la de GitHub o crear una cuenta. Todas estas opciones están disponibles en https://appcenter.ms/
Crear apps en App Center
Una vez que habéis creado una cuenta y os habéis logueado, es necesario crear tantas aplicaciones como SO móviles a los que se desea dar soporte. En este ejemplo, se van a implementar las notificaciones push tanto para Android como para iOS, así que será necesario crear 2 aplicaciones en el App Center.
En el panel principal de App Center se encuentra un botón en el que se puede agregar una nueva aplicación. Al pulsarlo, se solicita cierta información de esta aplicación
Una vez rellena la información, se crea esta aplicación. Será necesario crear dos aplicaciones, una para Android y otra para iOS
Una vez creadas las aplicaciones, el siguiente paso es configurar las notificaciones push para cada una de ellas.
Configurar App center para enviar notificaciones Android
Este punto es necesario para trabajar con notificaciones en Andorid. Para ello, hay que seguir estos pasos
Crear un proyecto en firebase
Tras crear el proyecto, pulsar sobre el icono de android para agregar una app.
Registrar la aplicación, para lo que se necesita el nombre del paquete android, que se puede encontrar en las propiedades del proyecto
Descargar el archivo de configuración
Una vez descargado, copiarlo en el proyecto Android
Cerrar y volver a abrir la solución de Visual Studio
Cambiar la acción de compilación del json descargado y fijarlo a GoogleServiceJson
Insertar en el manifiesto de android la siguiente información, en el apartado de aplicación.
<application ...> <!-- Add these lines --> <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> <!-- end of section to add --> </application>
El último paso para dejar firebase totalmente configurado es indicar su server key al app center. El server key de firebase se puede encontrar en la configuración de la aplicación, dentro del apartado Cloud Messaging.
Una vez copiado, solo hay que indicárselo al app center.
Configurar App center para enviar notificaciones iOS
Esta paso es necesario para trabajar con notificaciones en iOS. Para ello, hay que seguir los pasos que se indican en el app center, desde la configuración del servicio de notificaciones push.
En el proyecto iOS, hay que habilitar las notificaciones push en el archivo Entitlements.plis
El siguiente paso se realizará desde portal de desarrolladores de apple en el apartado de Certificates, identifiers & profiles, hay que crear una nueva key, habilitando el servicio Apple Push Notifications service (APNs)
Antes de finalizar con el asistente para la creación del Key, no hay que olvidar descargar el fichero.
Una vez que se ha terminado la creación del key, volvemos al app center (a la configuración del servicio de notificaciones push) y se informan los datos solicitados. Éstos son, el Key ID del Key que se acaba de crear, el prefijo y el identificador de nuestra aplicación.
Por último, hay que indicar el token de autenticación que se puede encontrar en el fichero asociado a la key, que hemos descargado previamente.
Configurar notificaciones push en proyecto Xamarin
Una vez que el app center ha quedado completamente configurado, tanto para Android como para iOS, es necesario incluir cierto código en nuestra aplicación Xamarin.Forms, tanto en la librería común como para cada plataforma. A continuación se detallan todas las tareas necesarias para recibir notificaciones push en nuestra app.
Añadir paquete Nuget
Añadir, tanto en nuestra aplicaciones Android e iOS de Xamarin como en nuestra librería común, el paquete nuget Microsoft.AppCenter.Push
Inicializar el paquete
En nuestro App.xaml.cs, es necesario sobreescribir el método OnStart para realizar la inicialización del app center y suscribirnos al evento que se lanzará al recibir una notificación
using Microsoft.AppCenter; using Microsoft.AppCenter.Push; using Xamarin.Forms; using Xamarin.Forms.Xaml; [assembly: XamlCompilation(XamlCompilationOptions.Compile)] namespace PushNotifications { public partial class App : Application { public App() { InitializeComponent(); MainPage = new MainPage(); } protected override void OnStart() { if (!AppCenter.Configured) Push.PushNotificationReceived += Push_PushNotificationReceived; AppCenter.Start("ios={YOUR_IOS_APP_KEY};" + "android={YOUR_ANDROID_APP_KEY};", typeof(Push)); } private void Push_PushNotificationReceived(object sender, PushNotificationReceivedEventArgs e) { // Add the notification message and title to the message var summary = $"Push notification received:" + $"\n\tNotification title: {e.Title}" + $"\n\tMessage: {e.Message}"; // If there is custom data associated with the notification, // print the entries if (e.CustomData != null) { summary += "\n\tCustom data:\n"; foreach (var key in e.CustomData.Keys) { summary += $"\t\t{key} : {e.CustomData[key]}\n"; } } // Send the notification summary to debug output System.Diagnostics.Debug.WriteLine(summary); } } }
Los APP keys se pueden encontrar en el app center, en la aplicación de cada plataforma, al entrar en el apartado de notificaciones push
Configuración propia de Android
Si el launchMode definido en el MainActivity.cs de Android es SingleTop, SingleInstance o SingleTask, es necesario sobrescribir el método OnNewIntent tal y como se muestra a continuación
protected override void OnNewIntent(Android.Content.Intent intent) { base.OnNewIntent(intent); Push.CheckLaunchedFromNotification(this, intent); }
Asimismo, si en nuestro proyecto Android tenemos un splash screen, es necesario cambiar la forma de inicializar el MainActivity, para que en su inicialización se indique correctamente toda la información del intent que pueda llegar al recibir una notificación
var intent = new Intent(this, typeof(MainActivity)); if (Intent.Extras != null) intent.PutExtras(Intent.Extras); // copy push info from splash to main StartActivity(intent);
Configuración propia de iOS
En el AppDelegate es necesario sobrescribir el método de la forma que a continuación se indica
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, System.Action completionHandler) { var result = Push.DidReceiveRemoteNotification(userInfo); if (result) completionHandler?.Invoke(UIBackgroundFetchResult.NewData); else completionHandler?.Invoke(UIBackgroundFetchResult.NoData); }
Enviando y recibiendo notificaciones Push
En este punto, ya podemos enviar una notificación push desde el app center y ésta será mostrada en nuestro dispositivo. Bastará con enviar una notificación desde el servicio de notificaciones push del app center (el de android o ios) e indicar la información que se solicita en cada uno de los pasos.
Una vez enviada, la notificación se recibirá en el dispositivo de la siguiente manera
- Si la aplicación está corriendo en primer plano, no se mostrará la notificación en el centro de notificaciones. Directamente se lanzará el evento Push_PushNotificationReceived
- Si la aplicación está corriendo en segundo plano o está cerrada, la notificación aparecerá en el centro de notificaciones. El evento Push_PushNotificationReceived no se lanzará hasta que se pulse sobre la notificación
En el objeto PushNotificationReceivedEventArgs se puede encontrar información sobre el título y el mensaje de la notificación, así como información personalizada enviada en una colección clave-valor
NOTA IMPORTANTE: Cuando estuve incluyendo las notificaciones push en uno de mis proyectos, me encontré con un «problema» (lo entrecomillo porque realmente no era un problema). El caso es que, una vez que cerraba la aplicación, no recibía ninguna notificación push. El problema era que la aplicación la lanzaba desde el depurador, y al cerrarla (por algún motivo que desconozco) está no queda suscrita a notificaciones push. La solución la encontré en estos sencillos pasos:
- Depurar la aplicación en nuestro dispositivo/emulador desde Visual Studio
- Para la depuración en VS
- Arrancar de nuevo la app desde el dispositivo/emulador
- Cerrar la aplicación
Tras estos pasos, las notificaciones push se reciben sin problemas.
Como siempre que escribo un post práctico, aquí os dejo un enlace a un proyecto de ejemplo en GitHub
https://github.com/jorgediegocrespo/XamarinPushNotifications
Un saludo!!
Bibliografia
Para realizar este post, me he basado en información que se puede encontrar en los siguientes enlaces