Von der FCM HTTP v1 API zu AndroidConfigV2 migrieren

Mit dem FCM AndroidConfigV2 können Sie intent-gesteuerte Nachrichten an Android-Geräte senden, die zeitnah zugestellt werden, und eine vereinfachte API nutzen.

In diesem Leitfaden wird beschrieben, wie Sie Ihre Backend-Sendeanfragen von AndroidConfig zu AndroidConfigV2 migrieren und wie Sie Ihre Android-App-Clients von der Legacy-onMessageReceived-Verarbeitung auf die neuen v2-Client-Callbacks onNotificationReceived und onBackgroundSyncReceived aktualisieren.

Neu in AndroidConfigV2

Die FCM AndroidConfigV2 API vereinfacht die Entwicklung durch die Einführung von zwei Nachrichtentypen:

  • RemoteNotification: Empfohlen für alle FCM-Nachrichten, die eine dringende, zeitkritische, für den Nutzer sichtbare Benachrichtigung anzeigen. Diese Nachrichten umgehen alle Energiesparmaßnahmen und werden ohne Verzögerung zugestellt. Auf dem Gerät übernehmen das FCM SDK und die Google Play-Dienste das Posten der Benachrichtigung im NotificationManager von Android.
  • BackgroundSync: Nicht dringende Datennachrichten für die Hintergrundsynchronisierung und Aktualisierungen des App-Status. Die Zustellung kann gebündelt oder verzögert werden, um die Akkulaufzeit zu optimieren.
Funktion Legacy (AndroidConfig v1) Neu (AndroidConfigV2)
Konfigurationsfeld message.android message.android_v2
Definition der Priorität Explizite priority: "high" oder priority: "normal" Impliziert durch Union-Typ (remote_notification für dringende Benachrichtigungen im Vergleich zu background_sync für nicht dringende Synchronisierung)
Benachrichtigungen posten App ruft NotificationManager.notify() manuell auf FCM SDK und GMS Core posten direkt oder über NotificationResponse
Client-Callbacks • onMessageReceived(RemoteMessage)
• onDeletedMessages()
• onNotificationReceived(RemoteMessage)
• onBackgroundSyncReceived(RemoteMessage)
• onDeletedMessages()
Minimierbarkeit Variiert; explizite Einstellung erforderlich Beide Nachrichtentypen können minimierbar oder nicht minimierbar sein (standardmäßig nicht minimierbar).

Sendeanfragen für AndroidConfigV2 autorisieren

Sie können weiterhin OAuth 2.0-Zugriffstokens verwenden, die von Ihrem Firebase-Dienstkonto mit Google-Standardanmeldedaten für Anwendungen oder dem Admin SDK abgeleitet wurden, und POST-Anfragen an den HTTP v1-Endpunkt messages:send senden.

Wenn Sie Ihr Firebase-Dienstkonto nicht verwenden, müssen Sie Ihrem dedizierten Konto die Rolle Firebase Cloud Messaging API Admin (roles/firebase.messagingAdmin) zuweisen und den OAuth 2.0-Bereich https://www.googleapis.com/auth/firebase.messaging anfordern, wenn Sie Zugriffstokens erstellen:

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

Sendeanfragen an den Server aktualisieren (REST)

Wenn Sie eine AndroidConfigV2-Anfrage über die REST API senden möchten, ersetzen Sie das android-Objekt im Anfragetext durch android_v2. Geben Sie in android_v2 allgemeine Parameter an (z. B. ttl, collapse_key, data und restricted_package_name) und geben Sie eines der folgenden Union-Felder an: remote_notification oder background_sync.

RemoteNotification-Nachricht senden

Wenn Sie eine dringende, für Nutzer sichtbare Benachrichtigung senden möchten, fügen Sie das Objekt remote_notification und die empfohlene Nutzlast notification ein. Standardmäßig ist mutable_content auf „false“ gesetzt. GMS Core rendert die Benachrichtigung sofort und postet sie in der Taskleiste, ohne Hintergrund-App-Code auszuführen.

Vollständiges JSON-Beispiel für eine HTTP-Anfrage (automatisch gerenderte Benachrichtigung)

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

RemoteNotification mit veränderbarem Inhalt senden

Wenn Ihre Anwendung die Benachrichtigung auf dem Gerät ändern muss, bevor sie angezeigt wird, legen Sie mutable_content: true in remote_notification fest. Dadurch wird GMS Core angewiesen, eine Bindung an Ihre Clientanwendung herzustellen und onNotificationReceived() aufzurufen. Das ist hilfreich, wenn Sie eine Ende-zu-Ende-verschlüsselte Nutzlast entschlüsseln, Nutzeravatare anhängen oder Strings lokalisieren möchten.

Achten Sie darauf, ein notification-Objekt in remote_notification einzufügen, auch wenn mutable_content den Wert true hat. GMS Core verwendet dieses notification-Objekt als Fallback-Benachrichtigung, wenn der Client-Callback das Zeitlimit überschreitet oder die Unterdrückungsgrenzen überschreitet.

Wenn Sie von älteren v1-Datennachrichten migrieren und möchten, dass FCM die Nutzlast als reine Datennachricht an ältere v1-Clientinstallationen liefert, legen Sie use_as_v1_data_message: true in remote_notification fest.

Vollständiges JSON-Beispiel für eine HTTP-Anfrage

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

BackgroundSync-Nachricht senden

Wenn Sie eine nicht dringende Nachricht für die Hintergrunddatensynchronisierung, automatische Statusaktualisierungen oder die Aktualisierung eines App-Badges oder Widgets senden möchten, verwenden Sie das Objekt background_sync. Verwenden Sie diese Nachrichten nicht, um für Nutzer sichtbare Benachrichtigungen zu posten, da diese zur Optimierung der Akkulaufzeit des Geräts im Batch oder verzögert gesendet werden können.

Vollständiges JSON-Beispiel für eine HTTP-Anfrage

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": {}
    }
  }
}

Android-Client-Callbacks aktualisieren

Wenn Sie AndroidConfigV2-Nachrichten unter Android empfangen möchten, müssen Sie Ihre App auf das neueste firebase-messaging SDK aktualisieren. Aktualisiere deinen Dienst, der FirebaseMessagingService erweitert, indem du onNotificationReceived() und onBackgroundSyncReceived() implementierst.

EAP SDK installieren

Während des EAP wird das firebase-messaging v2 SDK als lokales Maven-Repository-Archiv und nicht über das öffentliche Maven-Repository von Google bereitgestellt.

  1. Fügen Sie das Verzeichnis m2repository mit firebase-messaging:26.1.0-eap01 dem Stammverzeichnis Ihres Android-Projekts (<project-root>/m2repository) hinzu. Verwenden Sie dazu eine der folgenden Optionen:

    1. Option A: Vordefiniertes Archiv herunterladen: Laden Sie FirebaseMessaging_26.1.0-eap01.zip herunter und extrahieren Sie das Verzeichnis m2repository in das Stammverzeichnis Ihres Android-Projekts (<project-root>/m2repository).
    2. Option B: Mit Gradle aus GitHub erstellen: Klonen Sie den Zweig feature/fcm-android-config-v2-eap von firebase/firebase-android-sdk, erstellen Sie das lokale Maven-Repository und kopieren Sie das generierte Verzeichnis build/m2repository in das Stammverzeichnis Ihres Android-Projekts:

      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
      
  2. Fügen Sie in der Datei settings.gradle.kts (oder settings.gradle) auf Projektebene das lokale Verzeichnis m2repository am Anfang des Blocks repositories über google() hinzu:

    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()
        }
    }
    
  3. Aktualisieren Sie in der Datei app/build.gradle.kts (oder app/build.gradle) auf Modulebene die Abhängigkeit firebase-messaging auf 26.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'
    }
    
  4. Synchronisieren Sie Ihr Projekt mit Gradle-Dateien.

RemoteNotifications mit onNotificationReceived verarbeiten

Mit AndroidConfigV2 werden RemoteNotification-Nachrichten angezeigt, es sei denn, mutable_content ist auf „true“ gesetzt oder sie werden in onNotificationReceived() explizit unterdrückt.

Wenn ein RemoteNotification mit mutable_content: true eingeht, bindet GMS Core Ihre Anwendung ein und ruft onNotificationReceived() auf. Ihre Methode muss innerhalb von 20 Sekunden ein NotificationResponse zurückgeben.

Geänderte Benachrichtigung zurückgeben

Das Notification-Objekt, das Sie an NotificationResponse.create übergeben, ersetzt die in der Sendeanfrage definierten remote_notification.notification-Fallback-Nutzlastattribute des Servers. Wenn Sie Werte aus der Sendeanfrage beibehalten möchten, lesen Sie sie aus message.notification (message.getNotification() in Java) aus, während Sie Änderungen auf dem Gerät vornehmen:

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());
    }
}

Benachrichtigung unterdrücken

Wenn der Nutzer den entsprechenden Bildschirm oder Chat gerade geöffnet hat, kannst du die Benachrichtigung unterdrücken, indem du NotificationResponse.suppress() zurückgibst:

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());
}

Benachrichtigungen streamen oder ältere Benachrichtigungen abbrechen (FcmNotificationManager)

Wenn du mehrere Benachrichtigungen für einen einzelnen eingehenden Push posten oder eine veraltete Benachrichtigung abbrechen musst, bevor du eine neue anzeigst, verwende 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();
}

BackgroundSync-Nachrichten mit onBackgroundSyncReceived verarbeiten

Verwenden Sie onBackgroundSyncReceived(), um BackgroundSync-Nachrichten auf Android-Geräten zu verarbeiten:

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

Ausstehende Nachrichtenlöschungen mit onDeletedMessages verarbeiten

In einigen Situationen, z. B. wenn ein Gerät über einen längeren Zeitraum keine Verbindung zu FCM hergestellt hat oder die Serverwarteschlange voll ist, kann FCM ausstehende Nachrichten vor der Zustellung löschen. Überschreiben Sie in diesen Fällen 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();
}

Bestimmte Apps migrieren

Benachrichtigungen mit Ende-zu-Ende-Verschlüsselung (E2EE) senden

Wenn eine Ende-zu-Ende-verschlüsselte Benachrichtigung über einen RemoteNotification zugestellt wird, bleiben die entschlüsselten Benachrichtigungsinhalte in Ihrer App und auf der Android-Plattform:

  1. Änderbare Benachrichtigung senden: Ihr Server sendet eine RemoteNotification mit mutable_content: true, die verschlüsselte Nutzlast in data und ein generisches unverschlüsseltes Backup notification. GMS Core liefert die verschlüsselte Nachricht an das Open-Source-FCM-SDK in Ihrer App.
  2. Benachrichtigung entschlüsseln und zurückgeben: Das FCM SDK ruft onNotificationReceived() auf. Ihre App entschlüsselt die Nutzlast lokal, erstellt das endgültige entschlüsselte Android-Notification und übergibt es mit NotificationResponse oder FcmNotificationManager an das Open-Source-FCM-SDK.
  3. An Plattform posten und Metadaten melden: Das Open-Source-SDK von FCM postet die entschlüsselte Benachrichtigung direkt an die NotificationManager API der Android-Plattform und sendet nur Benachrichtigungsmetadaten wie Benachrichtigungs-IDs und Zeitstempel an GMS Core zurück, um die Zustellung zu beobachten. Entschlüsselte Inhalte werden niemals an GMS Core gesendet.
  4. Ersatzbenachrichtigung posten, falls erforderlich: Nur wenn Ihre App nicht innerhalb des Zeitlimits von 20 Sekunden antwortet oder die Limits für die Unterdrückung im Hintergrund überschreitet, postet GMS Core die generische Ersatzbenachrichtigung notification direkt auf der Android-Plattform.

Architekturdiagramm, das den vierstufigen Ablauf der Ende-zu-Ende-verschlüsselten Benachrichtigungszustellung zwischen GMS Core, dem Open-Source-FCM SDK, Ihrer App und der NotificationManager API der Android-Plattform zeigt.

Unterdrückung von Benachrichtigungen und Zeitlimits

Damit die Zustellung im Android-Ökosystem zuverlässig funktioniert, werden bei der Verarbeitung von RemoteNotification-Nachrichten durch GMS Core Zeitlimits für die Verarbeitung und Limits für die Unterdrückung von Benachrichtigungen angewendet:

Zeitüberschreitung bei der Verarbeitung

Wenn mutable_content auf true gesetzt ist, muss die Methode onNotificationReceived() innerhalb von 20 Sekunden ein NotificationResponse zurückgeben. Wenn die Ausführung diesen Schwellenwert überschreitet, wird der Callback abgebrochen und GMS Core sendet automatisch eine Fallback-Benachrichtigung, die aus der remote_notification.notification-Nutzlast gerendert wird.

Rate der unterdrückten Benachrichtigungen

Da RemoteNotification-Nachrichten die Einschränkungen des Stromsparmodus umgehen, um Nutzer sofort zu benachrichtigen, und ohne Verzögerung zugestellt werden, sollten Anwendungen Benachrichtigungen für empfangene RemoteNotification-Nachrichten anzeigen.

Jede Anwendung darf bis zu 25% ihres RemoteNotification-Traffics unterdrücken, während sie im Hintergrund ausgeführt wird. Wenn die Unterdrückungsrate einer App 25 % überschreitet, rendert und postet GMS Core automatisch eine Fallback-Benachrichtigung, die aus der remote_notification.notification-Nutzlast gerendert wird.

Unterdrückungen, die ausgeführt werden, wenn die Anwendung im Vordergrund aktiv ist, werden nicht auf diesen Schwellenwert angerechnet. Anwendungen, denen uneingeschränkte Berechtigungen für die Hintergrundnutzung gewährt wurden, sind ebenfalls von den Einschränkungen für die Hintergrundunterdrückung ausgenommen.