Von Legacy-FCM APIs zu HTTP v1 migrieren

Entwickler von Apps, die die veralteten FCM-APIs für HTTP und XMPP verwenden, sollten so bald wie möglich auf die HTTP v1 API umstellen. Das Senden von Nachrichten (einschließlich Upstream-Nachrichten) mit diesen APIs wurde am 20. Juni 2023 eingestellt und die Einstellung beginnt am 22. Juli 2024.

Weitere Informationen zu den betroffenen Funktionen

Neben der fortlaufenden Unterstützung und neuen Funktionen bietet die HTTP v1 API gegenüber den älteren APIs folgende Vorteile:

  • Mehr Sicherheit durch Zugriffstokens: Die HTTP v1 API verwendet kurzlebige Zugriffstokens gemäß dem OAuth2-Sicherheitsmodell. Wenn ein Zugriffstoken öffentlich wird, kann es nur etwa eine Stunde lang böswillig verwendet werden, bevor es abläuft. Aktualisierungstokens werden nicht so oft übertragen wie die Sicherheitsschlüssel, die in der alten API verwendet werden. Daher ist die Wahrscheinlichkeit, dass sie abgefangen werden, viel geringer.

  • Effizientere Anpassung von Nachrichten plattformübergreifend Für den Nachrichtentext verfügt die HTTP v1 API über gemeinsame Schlüssel, die an alle Zielinstanzen gesendet werden, sowie plattformspezifische Schlüssel, mit denen Sie die Nachricht plattformübergreifend anpassen können. So können Sie „Überschreibungen“ erstellen, mit denen in einer einzelnen Nachricht leicht unterschiedliche Nutzlasten an verschiedene Clientplattformen gesendet werden.

  • Erweiterbar und zukunftssicher für neue Clientplattformversionen Die HTTP v1 API unterstützt die auf Apple-Plattformen, Android und im Web verfügbaren Messaging-Optionen vollständig. Da jede Plattform einen eigenen Block in der JSON-Nutzlast hat, kann FCM die API bei Bedarf auf neue Versionen und neue Plattformen ausweiten.

Serverendpunkt aktualisieren

Die Endpunkt-URL für die HTTP v1 API unterscheidet sich in folgenden Punkten vom bisherigen Endpunkt:

  • Es ist versioniert und enthält /v1 im Pfad.
  • Der Pfad enthält die Projekt-ID des Firebase-Projekts für Ihre App im Format /projects/myproject-ID/. Diese ID finden Sie in der Firebase Console auf dem Tab Allgemeine Projekteinstellungen.
  • Die send-Methode wird hier explizit als :send angegeben.

Fügen Sie diese Elemente dem Endpunkt im Header Ihrer Sendeanfragen hinzu, um den Serverendpunkt für HTTP v1 zu aktualisieren.

HTTP-Anfragen vor

POST https://fcm.googleapis.com/fcm/send

XMPP-Anfragen vor

Alte XMPP-Nachrichten werden über eine Verbindung an den folgenden Endpunkt gesendet:

fcm-xmpp.googleapis.com:5235

Nachher

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send

Autorisierung von Sendeanfragen aktualisieren

Anstelle des Serverschlüsselstrings, der in älteren Anfragen verwendet wurde, ist für das Senden von HTTP v1-Anfragen ein OAuth 2.0-Zugriffstoken erforderlich. Wenn Sie Nachrichten über das Admin SDK senden, verarbeitet die Bibliothek das Token für Sie. Wenn du das EEF-Raw-Protokoll verwendest, erhalte das Token wie in diesem Abschnitt beschrieben und füge es dem Header als Authorization: Bearer <valid Oauth 2.0 token> hinzu.

Vorher

Authorization: key=AIzaSyZ-1u...0GBYzPu7Udno5aA

Nachher

Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

Je nach Details Ihrer Serverumgebung können Sie eine Kombination dieser Strategien verwenden, um Serveranfragen an Firebase-Dienste zu autorisieren:

  • Standardanmeldedaten für Google-Anwendungen (Application Default Credentials, ADC)
  • Eine JSON-Datei eines Dienstkontos
  • Ein kurzlebiges OAuth 2.0-Zugriffstoken, das von einem Dienstkonto abgeleitet wurde

Wenn Ihre Anwendung auf Compute Engine, Google Kubernetes Engine, App Engine oder Cloud Functions (einschließlich Cloud Functions for Firebase) ausgeführt wird, verwenden Sie Standardanmeldedaten für Anwendungen (Application Default Credentials, ADC). ADC verwendet Ihr vorhandenes Standarddienstkonto, um Anmeldedaten zur Autorisierung von Anfragen abzurufen. Außerdem ermöglicht ADC flexible lokale Tests über die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS. Für eine größtmögliche Automatisierung des Autorisierungsvorgangs sollten Sie ADC zusammen mit den Admin SDK-Serverbibliotheken verwenden.

Wenn Ihre Anwendung in einer anderen Serverumgebung als Google ausgeführt wird, müssen Sie eine JSON-Datei für das Dienstkonto aus Ihrem Firebase-Projekt herunterladen. Solange Sie Zugriff auf ein Dateisystem mit der privaten Schlüsseldatei haben, können Sie die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS verwenden, um Anfragen mit diesen manuell abgerufenen Anmeldedaten zu autorisieren. Wenn Sie keinen solchen Dateizugriff haben, müssen Sie in Ihrem Code auf die Dienstkontodatei verweisen. Dies sollte aufgrund des Risikos, dass Ihre Anmeldedaten offengelegt werden, mit äußerster Vorsicht erfolgen.

Anmeldedaten mit ADC bereitstellen

Bei Standardanmeldedaten für Google-Anwendungen (Application Default Credentials, ADC) wird in der folgenden Reihenfolge nach Ihren Anmeldedaten gesucht:

  1. ADC prüft, ob die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS festgelegt ist. Ist dies der Fall, wird die Dienstkontodatei, auf die die Variable verweist, für die Anmeldedaten verwendet.

  2. Wenn die Umgebungsvariable nicht festgelegt ist, verwendet ADC das Standarddienstkonto, das von Compute Engine, Google Kubernetes Engine, App Engine und Cloud Functions für Anwendungen bereitgestellt wird, die für diese Dienste ausgeführt werden.

  3. Wenn ADC keine der oben genannten Anmeldedaten verwenden kann, gibt das System einen Fehler aus.

Das folgende Codebeispiel für das Admin SDK veranschaulicht diese Strategie. In diesem Beispiel werden die Anmeldedaten für die Anwendung nicht explizit angegeben. Sie können aber im Rahmen dieses Vorgehens von ADC implizit ermittelt werden, sofern die Umgebungsvariable festgelegt ist oder die Anwendung in Compute Engine, Google Kubernetes Engine, App Engine oder Cloud Functions ausgeführt wird.

Node.js

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
});

Java

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
    .build();

FirebaseApp.initializeApp(options);

Python

default_app = firebase_admin.initialize_app()

Go

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

C#

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
});

Anmeldedaten manuell angeben

Firebase-Projekte unterstützen Google-Dienstkonten, mit denen Sie Firebase-Server-APIs von Ihrem App-Server oder einer vertrauenswürdigen Umgebung aus aufrufen können. Wenn Sie Code lokal entwickeln oder Ihre Anwendung vor Ort bereitstellen, können Sie über dieses Dienstkonto abgerufene Anmeldedaten verwenden, um Serveranfragen zu autorisieren.

Wenn Sie ein Dienstkonto authentifizieren und autorisieren möchten, auf Firebase-Dienste zuzugreifen, müssen Sie eine private Schlüsseldatei im JSON-Format generieren.

So generieren Sie eine private Schlüsseldatei für Ihr Dienstkonto:

  1. Öffnen Sie in der Firebase-Konsole Einstellungen > Dienstkonten.

  2. Klicke auf Neuen privaten Schlüssel generieren und bestätige die Aktion mit einem Klick auf Schlüssel generieren.

  3. Speichern Sie die JSON-Datei mit dem Schlüssel sicher.

Wenn Sie die Autorisierung über ein Dienstkonto vornehmen, haben Sie zwei Möglichkeiten, die Anmeldedaten für Ihre Anwendung bereitzustellen. Sie können entweder die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS festlegen oder den Pfad zum Dienstkontoschlüssel explizit im Code übergeben. Die erste Option ist sicherer und wird dringend empfohlen.

So legen Sie die Umgebungsvariable fest:

Legen Sie die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS auf den Pfad der JSON-Datei fest, die Ihren Dienstkontoschlüssel enthält. Diese Variable gilt nur für Ihre aktuelle Shellsitzung. Wenn Sie eine neue Sitzung öffnen, müssen Sie die Variable noch einmal festlegen.

Linux oder macOS

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

Windows

Mit PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

Nachdem Sie die oben genannten Schritte ausgeführt haben, können Ihre Anmeldedaten ermittelt werden, sodass Sie Dienstkontoanmeldedaten verwenden können, wenn Sie die Anwendung in Umgebungen testen oder ausführen, die nicht von Google stammen.

Anmeldedaten zum Generieren von Zugriffstokens verwenden

Verwenden Sie Ihre Firebase-Anmeldedaten zusammen mit der Google-Authentifizierungsbibliothek für Ihre bevorzugte Sprache, um ein kurzlebiges OAuth 2.0-Zugriffstoken abzurufen:

Node.js

 function getAccessToken() {
  return new Promise(function(resolve, reject) {
    const key = require('../placeholders/service-account.json');
    const jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      SCOPES,
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
}

In diesem Beispiel authentifiziert die Google API-Clientbibliothek die Anfrage mit einem JSON-Webtoken (JWT). Weitere Informationen finden Sie unter JSON Web Tokens.

Python

def _get_access_token():
  """Retrieve a valid access token that can be used to authorize requests.

  :return: Access token.
  """
  credentials = service_account.Credentials.from_service_account_file(
    'service-account.json', scopes=SCOPES)
  request = google.auth.transport.requests.Request()
  credentials.refresh(request)
  return credentials.token

Java

private static String getAccessToken() throws IOException {
  GoogleCredentials googleCredentials = GoogleCredentials
          .fromStream(new FileInputStream("service-account.json"))
          .createScoped(Arrays.asList(SCOPES));
  googleCredentials.refresh();
  return googleCredentials.getAccessToken().getTokenValue();
}

Nach Ablauf des Zugriffstokens wird die Tokenaktualisierungsmethode automatisch aufgerufen, um ein aktualisiertes Zugriffstoken abzurufen.

Fordern Sie den Bereich https://www.googleapis.com/auth/firebase.messaging an, um den Zugriff auf FCM zu autorisieren.

So fügen Sie das Zugriffstoken einem HTTP-Anfrageheader hinzu:

Fügen Sie das Token als Wert des Authorization-Headers im Format Authorization: Bearer <access_token> hinzu:

Node.js

headers: {
  'Authorization': 'Bearer ' + accessToken
}

Python

headers = {
  'Authorization': 'Bearer ' + _get_access_token(),
  'Content-Type': 'application/json; UTF-8',
}

Java

URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getServiceAccountAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

Nutzlast von Sendeanfragen aktualisieren

Mit FCM HTTP v1 wurde die Struktur der JSON-Nachrichtennutzlast erheblich geändert. In erster Linie stellen diese Änderungen sicher, dass Nachrichten korrekt verarbeitet werden, wenn sie auf verschiedenen Clientplattformen empfangen werden. Darüber hinaus bieten die Änderungen zusätzliche Flexibilität, um Nachrichtenfelder für jede Plattform anzupassen oder zu „überschreiben“.

Sehen Sie sich zusätzlich zu den Beispielen in diesem Abschnitt den Hilfeartikel Nachricht plattformübergreifend anpassen und die API-Referenz an, um sich mit HTTP v1 vertraut zu machen.

Beispiel: einfache Benachrichtigungsnachricht

Hier sehen Sie einen Vergleich einer sehr einfachen Benachrichtigungsnutzlast, die nur die Felder title, body und data enthält. Die grundlegenden Unterschiede zwischen alten und HTTP v1-Nutzlasten werden hier verdeutlicht.

Vorher

{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available."
  },
  "data": {
    "story_id": "story_12345"
  }
}

Nachher

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    }
  }
}

Beispiel: verschachtelte JSON-Daten

Im Gegensatz zur alten Messaging-API unterstützt die HTTP v1 API keine verschachtelten JSON-Werte im Feld data. Eine Konvertierung von JSON in einen String ist erforderlich.

Vorher

{
  ...
  "data": {
    "keysandvalues": {"key1": "value1", "key2": 123}
  }
}

Nachher

{
  "message": {
   ...
    "data": {
      "keysandvalues": "{\"key1\": \"value1\", \"key2\": 123}"
    }
  }
}

Beispiel: Targeting auf mehrere Plattformen

Um das Targeting auf mehrere Plattformen zu ermöglichen, führte die alte API Überschreibungen im Backend aus. Im Gegensatz dazu bietet HTTP v1 plattformspezifische Schlüsselblöcke, die Unterschiede zwischen den Plattformen explizit und für Entwickler sichtbar machen. So können Sie immer mit einer einzigen Anfrage auf mehrere Plattformen abzielen, wie im folgenden Beispiel gezeigt.

Vorher

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// Apple
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

Nachher

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    },
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Beispiel: Anpassung mit Plattformüberschreibungen

Die HTTP v1 API vereinfacht nicht nur das plattformübergreifende Targeting von Nachrichten, sondern bietet auch die Flexibilität, Nachrichten an die einzelnen Plattformen anzupassen.

Vorher

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "Check out the Top Story.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// Apple
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

Nachher

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    },
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY",
        "body": "Check out the Top Story"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Beispiel: Ausrichtung auf bestimmte Geräte

Wenn Sie mit der HTTP v1 API auf bestimmte Geräte abzielen möchten, geben Sie das aktuelle Registrierungstoken des Geräts im Schlüssel token anstelle des Schlüssels to an.

Vorher

  { "notification": {
      "body": "This is an FCM notification message!",
      "title": "FCM Message"
    },
    "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
  }

Nachher

{
   "message":{
      "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
      "notification":{
        "body":"This is an FCM notification message!",
        "title":"FCM Message"
      }
   }
}

Weitere Beispiele und Informationen zur FCM HTTP v1 API finden Sie hier: