Ce guide explique comment configurer Firebase Cloud Messaging dans vos applications clientes mobiles et Web pour recevoir des messages de manière fiable.
Pour recevoir des messages, utilisez un service qui étend FirebaseMessagingService
.
Votre service doit remplacer les rappels onMessageReceived
et onDeletedMessages
.
onMessageReceived
est disponible pour la plupart des types de messages, à l'exception des suivants :
Messages de notification envoyés lorsque votre application est en arrière-plan. Dans ce cas, la notification est envoyée dans la barre d'état système de l'appareil. Par défaut, lorsqu'un utilisateur appuie sur une notification, le lanceur d'applications s'ouvre.
Messages avec charge utile de notification et de données, lorsqu'ils sont reçus en arrière-plan. Dans ce cas, la notification est envoyée dans la barre d'état système de l'appareil, et la charge utile de données est envoyée dans les extras de l'intent de votre activité de lanceur.
En résumé :
État de l'application | Notification | Données | Les deux |
---|---|---|---|
Premier plan | onMessageReceived |
onMessageReceived |
onMessageReceived |
Arrière-plan | Barre d'état système | onMessageReceived |
Notification : barre d'état système Données : dans les extras de l'intention. |
Pour en savoir plus sur les types de messages, consultez Notifications et messages de données.
Le rappel onMessageReceived
reçoit des délais d'expiration qui vous permettent de publier une notification, mais les minuteurs ne sont pas conçus pour permettre à l'application d'accéder au réseau ou d'effectuer des tâches supplémentaires. Par conséquent, si votre application effectue des opérations plus complexes, vous devez effectuer des tâches supplémentaires pour vous assurer qu'elle peut les mener à bien.
Si vous pensez que votre application peut avoir besoin de près de 10 secondes pour traiter un message, vous devez planifier un job WorkManager ou suivre les conseils concernant WakeLock ci-dessous. Dans certains cas, le délai pour traiter un message peut être inférieur à 10 secondes en fonction des retards encourus avant l'appel de onMessageReceived
, y compris les retards de l'OS, le temps de démarrage de l'application, le blocage du thread principal par d'autres opérations ou les appels onMessageReceived
précédents qui ont pris trop de temps. Une fois ce minuteur expiré, votre application peut être soumise à des processus d'arrêt ou à des limites d'exécution en arrière-plan. N'oubliez pas que les latences pour les transactions réseau et le démarrage des applications peuvent être importantes. En cas de doute, prévoyez une longue durée d'exécution pour le traitement des messages s'il existe des dépendances asynchrones telles que l'accès au réseau ou des exigences de chargement intensif des données.
Modifier le fichier manifeste de l'application
Pour utiliser FirebaseMessagingService
, vous devez ajouter le code suivant au fichier manifeste de votre application :
<service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Il est également recommandé de définir des valeurs par défaut pour personnaliser l'apparence des notifications. Vous pouvez spécifier une icône et une couleur par défaut personnalisées qui sont appliquées chaque fois que des valeurs équivalentes ne sont pas définies dans la charge utile de la notification.
Ajoutez les lignes suivantes dans la balise application
pour définir l'icône et la couleur personnalisées par défaut :
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
Android affiche et utilise l'icône par défaut personnalisée pour
- Tous les messages de notification envoyés depuis le composant Notifications.
- Tout message de notification qui ne définit pas explicitement l'icône dans la charge utile de la notification.
Si aucune icône par défaut personnalisée n'est définie et qu'aucune icône n'est définie dans la charge utile de notification, Android affiche l'icône de l'application en blanc.
Ignorer onMessageReceived
En remplaçant la méthode FirebaseMessagingService.onMessageReceived
, vous pouvez effectuer des actions en fonction de l'objet RemoteMessage reçu et obtenir les données du message :
Kotlin
override fun onMessageReceived(remoteMessage: RemoteMessage) { // TODO(developer): Handle FCM messages here. // Not getting messages here? See why this may be: https://goo.gl/39bRNJ Log.d(TAG, "From: ${remoteMessage.from}") // Check if message contains a data payload. if (remoteMessage.data.isNotEmpty()) { Log.d(TAG, "Message data payload: ${remoteMessage.data}") // Check if data needs to be processed by long running job if (needsToBeScheduled()) { // For long-running tasks (10 seconds or more) use WorkManager. scheduleJob() } else { // Handle message within 10 seconds handleNow() } } // Check if message contains a notification payload. remoteMessage.notification?.let { Log.d(TAG, "Message Notification Body: ${it.body}") } // Also if you intend on generating your own notifications as a result of a received FCM // message, here is where that should be initiated. See sendNotification method below. }
Java
@Override public void onMessageReceived(RemoteMessage remoteMessage) { // TODO(developer): Handle FCM messages here. // Not getting messages here? See why this may be: https://goo.gl/39bRNJ Log.d(TAG, "From: " + remoteMessage.getFrom()); // Check if message contains a data payload. if (remoteMessage.getData().size() > 0) { Log.d(TAG, "Message data payload: " + remoteMessage.getData()); if (/* Check if data needs to be processed by long running job */ true) { // For long-running tasks (10 seconds or more) use WorkManager. scheduleJob(); } else { // Handle message within 10 seconds handleNow(); } } // Check if message contains a notification payload. if (remoteMessage.getNotification() != null) { Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody()); } // Also if you intend on generating your own notifications as a result of a received FCM // message, here is where that should be initiated. See sendNotification method below. }
Maintenir l'appareil activé lors du traitement des messages FCM
Si votre application doit maintenir l'appareil en éveil pendant le traitement d'un message FCM, elle devra conserver un WakeLock pendant cette période ou créer un job WorkManager. Les WakeLocks fonctionnent bien pour les activités de traitement courtes qui peuvent dépasser les délais d'attente par défaut de onMessageReceived
. Pour les workflows étendus, tels que l'envoi de plusieurs RPC sériels à vos serveurs, il est plus approprié d'utiliser un job WorkManager qu'un WakeLock. Dans cette section, nous allons nous concentrer sur l'utilisation des WakeLocks. Un WakeLock empêche l'appareil de se mettre en veille pendant l'exécution de votre application, ce qui peut entraîner une augmentation de la consommation de batterie. L'utilisation de WakeLocks doit donc être réservée aux cas où votre application ne doit pas être mise en pause lors du traitement du message, par exemple :
- Notifications urgentes envoyées à l'utilisateur.
- Interactions avec un élément hors de l'appareil qui ne doivent pas être interrompues (comme les transferts réseau ou les communications avec un autre appareil, comme une montre associée).
Tout d'abord, vous devez vous assurer que votre application demande l'autorisation WakeLock (le SDK FCM l'inclut par défaut, donc normalement, rien n'a besoin d'être ajouté).
<uses-permission android:name="android.permission.WAKE_LOCK" />
Votre application devra ensuite acquérir un WakeLock au début du rappel FirebaseMessagingService.onMessageReceived()
et le libérer à la fin du rappel.
FirebaseMessagingService
personnalisé de l'application :
@Override
public void onMessageReceived(final RemoteMessage message) {
// If this is a message that is time sensitive or shouldn't be interrupted
WakeLock wakeLock = getSystemService(PowerManager.class).newWakeLock(PARTIAL_WAKE_LOCK, "myApp:messageReceived");
try {
wakeLock.acquire(TIMEOUT_MS);
// handle message
...
finally {
wakeLock.release();
}
}
Ignorer onDeletedMessages
Dans certains cas, FCM ne peut pas envoyer de message. Cela se produit lorsqu'il y a trop de messages (> 100) en attente pour votre application sur un appareil spécifique au moment où il se connecte, ou si l'appareil ne s'est pas connecté à FCM depuis plus d'un mois. Dans ce cas, vous pouvez recevoir un appel au FirebaseMessagingService.onDeletedMessages()
. Lorsque l'instance d'application reçoit ce rappel, elle doit effectuer une synchronisation complète avec le serveur de votre application. Si vous n'avez pas envoyé de message à l'application sur cet appareil au cours des quatre dernières semaines, FCM ne passera pas d'appel onDeletedMessages()
.
Gérer les messages de notification dans une application en arrière-plan
Lorsque votre application est en arrière-plan, Android redirige les messages de notification vers la barre d'état système. Par défaut, lorsqu'un utilisateur appuie sur la notification, le lanceur d'applications s'ouvre.
Cela inclut les messages contenant à la fois une charge utile de notification et de données (ainsi que tous les messages envoyés depuis la console Notifications). Dans ce cas, la notification est envoyée dans la barre d'état système de l'appareil, et la charge utile de données est envoyée dans les extras de l'intent de votre activité de lanceur.
Pour en savoir plus sur la distribution des messages à votre application, consultez le
tableau de bord des rapports FCM, qui enregistre le nombre de messages envoyés et ouverts sur les appareils Apple et Android, ainsi que les données sur les "impressions" (notifications vues par les utilisateurs) pour les applications Android.