Loupe

Mise en place de push notifications dans vos applications Xamarin avec Firebase 2/2 : Xamarin.Android

Comme dit dans l'article précédant concernant la mise en place de notification push pour Xamarin.iOS, Firebase est une plateforme qui propose différents services pour web-app et mobile. Le service qui va nous intéresser est Firebase Cloud Messaging qui permet d'envoyer des notifications à tous les devices.

Dans cet article, nous allons nous concentrer cette fois sur la mise en place de push notifications sur vos application Xamarin.Android.

Création projet Firebase

Tout d'abord, comme pour l'application Xamarin.iOS, il vous faut un projet Firebase. Alors si vous n'en avez pas encore un, créez un projet Firebase depuis la console Firebase. Suivez les étapes jusqu'à "Créez votre projet". Si vous avez suivi l'article précédant, ou que vous possédez déjà un projet Firebase, vous pouvez réutiliser ce projet.01-Firebase-create.png

Une fois le projet créé ou sélectionné, ajoutez une application Android au niveau du portail. Votre nom de package d'application Android vous sera demandé. A l'étape suivante, téléchargez le fichier google-services.json et gardez le bien précieusement, il vous sera utile par la suite. Ce fichier contient tous les paramètres nécessaires pour se connecter à Firebase. Passez ensuite toutes les autres étapes.

03-Firebase-add-app.png
04-Firebase-add-app.png

Configurer FCM dans l'application

Aucune autre action de votre part ne sera requise sur la console Firebase, passons donc au projet Xamarin.Android.

Ajoutez le fichier google-services.json à la racine de votre projet et définissez l'action de génération à GoogleServicesJson.

09-Xamarin-Add-GoogleServicecs.PNG

Ouvrez le fichier et vérifiez que le package_name correspond à celui de votre projet que vous avez défini dans votre AndroidManifest.xml.

Votre application aura besoin des packages des Google Play Services et de Firebase. Ajoutez donc le package NuGet Xamarin.GooglePlayServices.Base puis le package NuGet Xamarin.Firebase.Messaging

Lorsque le fichier google-services.json est ajouté au projet et que l'action de génération est définie à GoogleServicesJson, le processus de génération extrait l'ID client et la clé API, puis ajoute ces informations d'identification au fichier AndroidManifest.xml généré (obj/Debug/android/AndroidManifest.xml). Ce processus de fusion ajoute automatiquement les autorisations et les autres éléments FCM nécessaires à la connexion aux serveurs FCM.

MainActivity

Avant de pouvoir utiliser les notifications, il faut vérifier que les Google Play Services sont disponibles (vérifier si l'APK de Google Play Services est installée). S'ils ne sont pas disponibles, alors le device ne pourra jamais recevoir de notifications. Dans certains cas, l'application devient inutilisable et il devient pertinent de terminer l'application avec l'instruction Finish()après en avoir notifié l'utilisateur. Dans le cas ou les Google Play Services ne sont pas disponibles mais que l'erreur peut être résolue, alors vous devriez conseiller à l'utilisateur d'installer l'apk Google Play Services. 

 public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
	...
	IsPlayServicesAvailable()
}

public bool IsPlayServicesAvailable ()
{
    int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable (this);
    if (resultCode != ConnectionResult.Success)
    {
        if (GoogleApiAvailability.Instance.IsUserResolvableError (resultCode))
		{
			//Should install apk
		}
        else
        {
            //This device is not supported
            //Should notify the user
        }
        return false;
    }
    else
    {
        //Google Play Services is available
        return true;
    }
}

AndroidManifest

Ajouter ceci dans la balise <application> de votre manifeste afin d'enregistrer les services permettant recevoir les notifications et le token d'enregistrement à Firebase (dont je reparlerais tout de suite) :

<receiver
	android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
	android:exported="false" />

<!-- provides a unique identifier for each app instance -->
<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}" /> <!-- stored in the google-services.json -->
	</intent-filter>
</receiver>

Réception du token d'enregistrement

Dans le cas des push notifications, Firebase fournit un token permettant d'identifier le device. Celui-ci pourra être utilisé par un serveur applicatif pour envoyer des notifications à un utilisateur en particulier.

Afin de gérer la création, rotation et mise à jour des tokens d'enregistrement de Firebase, il est nécessaire d'ajouter un service qui étend FirebaseInstanceIdService. Ce service implémente la méthode OnTokenRefresh.

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

OnTokenRefresh est invoquée quand le token a changé, ce qui arrive quand :

  • l'application est installée ou désinstallée ;
  • l'utilisateur supprime les données de l'application ;
  • l'application supprime l'Instance ID ;
  • la sécurité du token est compromise.

Réception de notifications

On peut distinguer deux cas pour la réception de notifications : en background et en foreground. La notification n'est pas construite de la même façon en fonction de ceci.

Les notifications de type notification (incluant la clé notification) seront traitées seulement au premier plan. La méthode OnMessageReceived décrite dans le point suivant n'est appelée que pour construire la notification, tout autre traitement sera fait seulement lorsque d'application repassera au premier plan.

Ensuite, les notifications de type donnée (incluant la clé data) seront traitées, elles, en arrière plan ainsi qu'au premier plan. Elles sont souvent utilisées pour le téléchargement de données en arrière-plan.

Notifications au premier plan

Afin de recevoir les notifications lorsque l'application est au premier plan, il faut implementer le service FirebaseMessagingService. Le service FirebaseMessagingService est responsable de la réception et du traitement des messages de Firebase. Toutes les application doivent implémenter ce service et la méthode OnMessageReceived pour recevoir des notifications.

[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT"})]
class MyFirebaseMessagingService : FirebaseMessagingService
{
	internal static readonly string TAG = "MyFirebaseMessagingService";

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

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

		//Do whatever you want here
	}
}

Pour afficher la notification dans le centre de notifications, vous pouvez ajouter la méthode suivante et l'appeler dans le corps de OnMessageReceived.

private void SendNotification(string messageBody, IDictionary<string, string> data)
{
	//Activity which should be launch when user click on notification
	var intent = new Intent(this, typeof(MainActivity));

	//Add notification parameters to intent
	intent.AddFlags(ActivityFlags.ClearTop);
	foreach (var key in data.Keys)
	{
		intent.PutExtra(key, data[key]);
	}

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

	var notificationBuilder = new NotificationCompat.Builder(this)
								.SetSmallIcon(Resource.Mipmap.Icon)
								.SetContentTitle("FCM Message")
								.SetContentText(messageBody)
								.SetAutoCancel(true)
								.SetContentIntent(pendingIntent);

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

Ici, la variable notificationBuilder définit l'icone à afficher pour la notification, son titre, son contenu, et l'activité (intent) qui doit être démarrée lorsque l'utilisateur clique sur la notification.

Pour rappel, dans une notification de type notification, seule la construction de la notification sera faite en arrière plan, tout autre traitement se fera quand l'application sera réouverte.

Notifications en arrière-plan

Si le type de la notification envoyée avec FCM est donnée (en incluant l'objet data dans le payload), alors la méthode OnMessageReceived sera appelée, de la même façon que lorsque l'application est au premier-plan, même si l'application est en background.

Ceci permet d'ajouter d'autres traitements en arrière-plan comme le téléchargement de données, ce pour quoi je vous recommande l'utilisation de JobService.

TADA quel plaisir encore une fois de voir apparaitre ces notifications sur votre téléphone ! :)

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus