FCM AndroidConfigV2 vous permet d'envoyer des messages basés sur l'intent aux appareils Android, avec une distribution des notifications en temps opportun et une API simplifiée.
Ce guide explique comment migrer vos requêtes d'envoi de backend de AndroidConfig vers AndroidConfigV2, et comment mettre à jour vos clients d'application Android pour passer de l'ancienne gestion onMessageReceived aux nouveaux rappels client v2 onNotificationReceived et onBackgroundSyncReceived.
Nouveautés d'AndroidConfigV2
L'API FCM AndroidConfigV2 simplifie l'expérience des développeurs en introduisant deux types de messages :
RemoteNotification: recommandé pour tous les messages FCM qui affichent une notification urgente, sensible au facteur temps et visible par l'utilisateur. Ces messages contournent toutes les mesures d'économie de batterie et sont distribués sans délai. Sur l'appareil, le SDK FCM et les services Google Play se chargent de publier la notification dans leNotificationManagerd'Android.BackgroundSync: messages de données non urgents destinés à la synchronisation en arrière-plan et aux mises à jour de l'état de l'application. La distribution peut être groupée ou retardée pour optimiser l'autonomie de la batterie.
| Fonctionnalité | Ancienne (AndroidConfig v1) |
Nouveau (AndroidConfigV2) |
|---|---|---|
| Champ de configuration | message.android |
message.android_v2 |
| Définition de la priorité | priority: "high" ou priority: "normal" explicite |
Implicite par type d'union (remote_notification pour les alertes urgentes et background_sync pour la synchronisation non urgente) |
| Publication de notifications | L'application appelle manuellement NotificationManager.notify() |
Publiez directement le SDK FCM et GMS Core, ou utilisez NotificationResponse. |
| Rappels client | • onMessageReceived(RemoteMessage)• onDeletedMessages() |
• onNotificationReceived(RemoteMessage)• onBackgroundSyncReceived(RemoteMessage)• onDeletedMessages() |
| Réductibilité | Variable ; paramètre explicite requis | Les deux types de messages peuvent être réductibles ou non (non réductibles par défaut). |
Autoriser les requêtes d'envoi AndroidConfigV2
Vous pouvez continuer à utiliser les jetons d'accès OAuth 2.0 dérivés de votre compte de service Firebase à l'aide des identifiants par défaut de l'application Google ou du SDK Admin, et envoyer des requêtes POST au point de terminaison HTTP v1 messages:send.
Si vous n'utilisez pas votre compte de service Firebase, veillez à attribuer à votre compte dédié le rôle Administrateur de l'API Firebase Cloud Messaging (roles/firebase.messagingAdmin) et à demander le champ d'application OAuth 2.0 https://www.googleapis.com/auth/firebase.messaging lors de la création des jetons d'accès :
POST https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send HTTP/1.1
Authorization: Bearer YOUR_OAUTH_ACCESS_TOKEN
Content-Type: application/json
Mettre à jour les requêtes d'envoi du serveur (REST)
Pour envoyer une requête AndroidConfigV2 à l'aide de l'API REST, remplacez l'objet android dans le corps de votre requête par android_v2. Dans android_v2, spécifiez les paramètres courants (tels que ttl, collapse_key, data et restricted_package_name), puis indiquez l'un des champs d'union suivants : remote_notification ou background_sync.
Envoyer un message RemoteNotification
Pour envoyer une notification urgente visible par l'utilisateur, incluez l'objet remote_notification et sa charge utile notification recommandée. Par défaut, mutable_content est défini sur "false". GMS Core affiche et publie immédiatement la notification dans la barre d'état système sans exécuter le code de l'application en arrière-plan.
Exemple de requête HTTP JSON complète (notification affichée automatiquement)
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message": {
"token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification": {
"title": "FCM Message",
"body": "This is an FCM notification message!"
},
"android_v2": {
"ttl": "3600s",
"remote_notification": {
"mutable_content": false,
"notification": {
"title": "Order update",
"body": "Your order has been shipped!",
"icon": "ic_notification_custom",
"sound": "default",
"tag": "alert_tag_1",
"id": 100
}
}
}
}
}
Envoyer une RemoteNotification avec du contenu modifiable
Si votre application doit modifier la notification sur l'appareil avant qu'elle ne s'affiche, définissez mutable_content: true dans remote_notification. Cela indique à GMS Core de se lier à votre application cliente et d'appeler onNotificationReceived(). Cela est utile lorsque vous souhaitez déchiffrer une charge utile chiffrée de bout en bout, joindre des avatars d'utilisateurs ou localiser des chaînes.
Veillez à inclure un objet notification dans remote_notification, même lorsque mutable_content est défini sur true. GMS Core utilise cet objet notification comme notification de remplacement si le rappel du client expire ou dépasse les limites de suppression.
Si vous migrez depuis d'anciens messages de données v1 et que vous souhaitez que FCM transmette la charge utile aux anciennes installations clientes v1 en tant que message de données pur, définissez use_as_v1_data_message: true dans remote_notification.
Exemple de requête HTTP JSON complète
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message": {
"token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data": {
"encrypted_content": "U2FsdGVkX19vN2m+",
"sender_id": "user_98124"
},
"android_v2": {
"ttl": "3600s",
"remote_notification": {
"mutable_content": true,
"use_as_v1_data_message": true,
"notification": {
"title": "New message",
"body": "You have a new message",
"tag": "chat_alert",
"id": 1001
}
}
}
}
}
Envoyer un message BackgroundSync
Pour envoyer un message non urgent pour la synchronisation des données en arrière-plan, les mises à jour d'état silencieuses ou la mise à jour d'un badge ou d'un widget d'application, utilisez l'objet background_sync.
N'utilisez pas ces messages pour publier des notifications visibles par l'utilisateur, car elles peuvent être regroupées ou retardées pour optimiser l'autonomie de la batterie de l'appareil.
Exemple de requête HTTP JSON complète
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message": {
"token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data": {
"score": "FETCH_UPDATES",
"sync_action": "FETCH_UPDATES"
},
"android_v2": {
"ttl": "86400s",
"collapse_key": "app_state_sync",
"background_sync": {}
}
}
}
Mettre à jour les rappels du client Android
Pour recevoir des messages AndroidConfigV2 sur Android, mettez à niveau votre application afin d'utiliser le dernier SDK firebase-messaging. Mettez à jour votre service en étendant FirebaseMessagingService en implémentant onNotificationReceived() et onBackgroundSyncReceived().
Installer le SDK EAP
Pendant le programme d'accès anticipé, le SDK firebase-messaging v2 est distribué sous forme d'archive de dépôt Maven local plutôt que via le dépôt Maven public de Google.
Ajoutez le répertoire
m2repositorycontenantfirebase-messaging:26.1.0-eap01au répertoire racine de votre projet Android (<project-root>/m2repository) à l'aide de l'une des options suivantes :- Option A : Télécharger l'archive prédéfinie : téléchargez FirebaseMessaging_26.1.0-eap01.zip et extrayez le répertoire
m2repositorydans le répertoire racine de votre projet Android (<project-root>/m2repository). Option B : compiler à partir de GitHub avec Gradle : clonez la branche
feature/fcm-android-config-v2-eapdefirebase/firebase-android-sdk, compilez le dépôt Maven local et copiez le répertoirebuild/m2repositorygénéré à la racine de votre projet Android :git clone --branch feature/fcm-android-config-v2-eap --single-branch \ https://github.com/firebase/firebase-android-sdk.git cd firebase-android-sdk ./gradlew -PprojectsToPublish="firebase-messaging" firebasePublish cp -R build/m2repository /path/to/your/android-project/m2repository
- Option A : Télécharger l'archive prédéfinie : téléchargez FirebaseMessaging_26.1.0-eap01.zip et extrayez le répertoire
Dans le fichier
settings.gradle.kts(ousettings.gradle) au niveau du projet, ajoutez le répertoirem2repositorylocal en haut du blocrepositories, au-dessus degoogle():Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url = uri("${rootDir}/m2repository") } google() mavenCentral() } }Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url "${rootDir}/m2repository" } google() mavenCentral() } }Dans le fichier
app/build.gradle.kts(ouapp/build.gradle) au niveau du module, remplacez votre dépendancefirebase-messagingpar26.1.0-eap01:Kotlin
dependencies { implementation("com.google.firebase:firebase-messaging:26.1.0-eap01") }Groovy
dependencies { implementation 'com.google.firebase:firebase-messaging:26.1.0-eap01' }Synchronisez votre projet avec les fichiers Gradle.
Gérer les RemoteNotifications avec onNotificationReceived
Avec AndroidConfigV2, les messages RemoteNotification sont affichés, sauf si mutable_content est défini sur "true" ou s'ils sont explicitement désactivés dans onNotificationReceived().
Lorsqu'un RemoteNotification arrive avec mutable_content: true, GMS Core se lie à votre application et appelle onNotificationReceived(). Votre méthode doit renvoyer un NotificationResponse dans un délai de 20 secondes.
Renvoyer une notification modifiée
L'objet Notification que vous transmettez à NotificationResponse.create remplace les propriétés de charge utile de remplacement remote_notification.notification du serveur définies dans la requête d'envoi. Pour conserver les valeurs de la requête d'envoi, lisez-les à partir de message.notification (message.getNotification() en Java) tout en appliquant les modifications sur l'appareil :
Kotlin
import androidx.core.app.NotificationCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.NotificationResponse
import com.google.firebase.messaging.RemoteMessage
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onNotificationReceived(message: RemoteMessage): NotificationResponse {
val serverNotif = message.notification
val channelId = serverNotif?.channelId ?: "default_channel"
// Keep the server-defined title unchanged, or fall back to default
val title = serverNotif?.title ?: "New message"
// Modify the notification body on-device (for example, decrypting data)
val decryptedBody = decryptPayload(message.data["encrypted_content"])
val builder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(title)
.setContentText(decryptedBody)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
// Return the response for the open-source FCM SDK to post to the Android platform
return NotificationResponse.create("optional_tag", 100, builder.build())
}
}
Java
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import com.google.firebase.messaging.NotificationResponse;
import androidx.core.app.NotificationCompat;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public NotificationResponse onNotificationReceived(RemoteMessage message) {
RemoteMessage.Notification serverNotif = message.getNotification();
String channelId = (serverNotif != null && serverNotif.getChannelId() != null)
? serverNotif.getChannelId()
: "default_channel";
// Keep the server-defined title unchanged, or fall back to default
String title = (serverNotif != null && serverNotif.getTitle() != null)
? serverNotif.getTitle()
: "New message";
// Modify the notification body on-device (for example, decrypting data)
String decryptedBody = decryptPayload(message.getData().get("encrypted_content"));
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(title)
.setContentText(decryptedBody)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true);
// Return the response for the open-source FCM SDK to post to the Android platform
return NotificationResponse.create("optional_tag", 100, builder.build());
}
}
Supprimer une notification
Si l'utilisateur a actuellement l'écran ou le chat approprié actif, vous pouvez supprimer la notification en renvoyant NotificationResponse.suppress() :
Kotlin
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ProcessLifecycleOwner
override fun onNotificationReceived(message: RemoteMessage): NotificationResponse {
val chatId = message.data["chat_id"]
val isAppForeground = ProcessLifecycleOwner.get()
.lifecycle
.currentState
.isAtLeast(Lifecycle.State.STARTED)
if (isAppForeground && chatRepository.isConversationActive(chatId)) {
// Suppress notification display because the user is actively viewing this chat
return NotificationResponse.suppress()
}
val builder = buildNotificationForChat(message)
return NotificationResponse.create("chat_tag", 101, builder.build())
}
Java
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.ProcessLifecycleOwner;
@Override
public NotificationResponse onNotificationReceived(RemoteMessage message) {
String chatId = message.getData().get("chat_id");
boolean isAppForeground = ProcessLifecycleOwner.get()
.getLifecycle()
.getCurrentState()
.isAtLeast(Lifecycle.State.STARTED);
if (isAppForeground && chatRepository.isConversationActive(chatId)) {
// Suppress notification display because the user is actively viewing this chat
return NotificationResponse.suppress();
}
NotificationCompat.Builder builder = buildNotificationForChat(message);
return NotificationResponse.create("chat_tag", 101, builder.build());
}
Diffuser des notifications ou annuler des alertes plus anciennes (FcmNotificationManager)
Si vous devez publier plusieurs notifications pour un seul push entrant ou annuler une notification obsolète avant d'en afficher une nouvelle, utilisez FcmNotificationManager :
Kotlin
override fun onNotificationReceived(message: RemoteMessage): NotificationResponse {
// Retrieve the scoped manager for this message execution
val manager = getFcmNotificationManager(message)
// 1. Cancel an outdated notification right away
manager.cancelNow("message_tag", 50)
// 2. Post the item notification immediately
val itemNotif = NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("Alex")
.setContentText(message.data["text"])
manager.postNow("item_tag", 51, itemNotif.build())
// 3. Post a group summary notification
val summaryNotif = NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("New Conversations")
.setGroupSummary(true)
manager.postNow("summary_tag", 52, summaryNotif.build())
// 4. Return finished() to complete the streaming workflow
return manager.finished()
}
Java
@Override
public NotificationResponse onNotificationReceived(RemoteMessage message) {
// Retrieve the scoped manager for this message execution
FcmNotificationManager manager = getFcmNotificationManager(message);
// 1. Cancel an outdated notification right away
manager.cancelNow("message_tag", 50);
// 2. Post the item notification immediately
NotificationCompat.Builder itemNotif = new NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("Alex")
.setContentText(message.getData().get("text"));
manager.postNow("item_tag", 51, itemNotif.build());
// 3. Post a group summary notification
NotificationCompat.Builder summaryNotif = new NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("New Conversations")
.setGroupSummary(true);
manager.postNow("summary_tag", 52, summaryNotif.build());
// 4. Return finished() to complete the streaming workflow
return manager.finished();
}
Gérer les messages BackgroundSync à l'aide de onBackgroundSyncReceived
Pour traiter les messages BackgroundSync sur Android, utilisez onBackgroundSyncReceived() :
Kotlin
override fun onBackgroundSyncReceived(message: RemoteMessage) {
val syncCommand = message.data["sync_action"]
try {
// Perform local database synchronization or cache refresh
AppDataRepository.getInstance(applicationContext).syncWithServer(syncCommand)
} catch (e: Exception) {
Log.e("FCM", "Background sync operation failed", e)
}
// Execution completes -> GMS Core marks the message as handled and unbinds.
}
Java
@Override
public void onBackgroundSyncReceived(RemoteMessage message) {
String syncCommand = message.getData().get("sync_action");
try {
// Perform local database synchronization or cache refresh
AppDataRepository.getInstance(getApplicationContext()).syncWithServer(syncCommand);
} catch (Exception e) {
Log.e("FCM", "Background sync operation failed", e);
}
// Execution completes -> GMS Core marks the message as handled and unbinds.
}
Gérer les suppressions de messages en attente à l'aide de onDeletedMessages
Dans certains cas, par exemple lorsqu'un appareil ne s'est pas connecté à FCM pendant une période prolongée ou lorsque la file d'attente du serveur est pleine, FCM peut supprimer les messages en attente avant leur distribution. Dans ce cas, remplacez onDeletedMessages() :
Kotlin
override fun onDeletedMessages() {
// Perform a full state synchronization with your app server
AppDataRepository.getInstance(applicationContext).scheduleFullSync()
}
Java
@Override
public void onDeletedMessages() {
// Perform a full state synchronization with your app server
AppDataRepository.getInstance(getApplicationContext()).scheduleFullSync();
}
Migrer des applications spécifiques
Envoyer des notifications chiffrées de bout en bout (E2EE)
Lors de l'envoi d'une notification chiffrée de bout en bout à l'aide d'un RemoteNotification, le contenu de la notification déchiffrée reste dans votre application et sur la plate-forme Android :
- Envoyer une notification modifiable : votre serveur envoie un
RemoteNotificationavecmutable_content: true, la charge utile chiffrée dansdataet une sauvegarde générique non chiffréenotification. GMS Core transmet le message chiffré au SDK FCM Open Source dans votre application. - Déchiffrer et renvoyer la notification : le SDK FCM appelle
onNotificationReceived(). Votre application déchiffre la charge utile localement, crée leNotificationAndroid déchiffré final et le transmet au SDK FCM Open Source à l'aide deNotificationResponseouFcmNotificationManager. - Publier sur la plate-forme et signaler les métadonnées : le SDK FCM Open Source publie la notification déchiffrée directement dans l'API
NotificationManagerde la plate-forme Android et n'envoie que les métadonnées de notification, telles que les ID de notification et les codes temporels, à GMS Core pour l'observabilité de la diffusion. Le contenu déchiffré n'est jamais envoyé à GMS Core. - Publier une notification de sauvegarde si nécessaire : GMS Core ne publie la notification de sauvegarde générique
notificationdirectement sur la plate-forme Android que si votre application ne répond pas dans le délai de 20 secondes ou dépasse les limites de suppression en arrière-plan.

Comprendre la suppression et les délais avant expiration des notifications
Pour assurer une distribution fiable dans l'écosystème Android, GMS Core applique des délais avant expiration du traitement et des limites de suppression des notifications lors du traitement des messages RemoteNotification :
Délai avant expiration du traitement
Lorsque mutable_content est défini sur true, votre méthode onNotificationReceived() doit renvoyer un NotificationResponse dans un délai de 20 secondes. Si l'exécution dépasse ce seuil, le rappel est annulé et GMS Core publie automatiquement une notification de remplacement affichée à partir de la charge utile remote_notification.notification.
Taux de suppression des notifications
Étant donné que les messages RemoteNotification contournent les restrictions du mode Sommeil pour alerter immédiatement les utilisateurs et sont distribués sans délai, les applications doivent afficher des notifications pour les messages RemoteNotification reçus.
Chaque application est autorisée à supprimer jusqu'à 25% de son trafic RemoteNotification lorsqu'elle s'exécute en arrière-plan. Si le taux de suppression d'une application dépasse 25%, GMS Core affiche et publie automatiquement une notification de remplacement à partir de la charge utile remote_notification.notification.
Les suppressions effectuées lorsque l'application est active au premier plan ne sont pas comptabilisées dans ce seuil. Les applications disposant d'autorisations d'utilisation en arrière-plan sans restriction sont également exemptées des limites de suppression en arrière-plan.