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. Sollte ein Zugriffstoken öffentlich werden, kann es nur etwa eine Stunde lang für böswillige Zwecke 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 plattformübergreifende Anpassung von Nachrichten: Die HTTP v1 API bietet für den Nachrichtentext 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.

  • Erweiterbarer und zukunftssicherer für neue Clientplattformversionen: Die HTTP v1 API unterstützt vollständig die Messaging-Optionen, die auf Apple-Plattformen, Android und im Web verfügbar sind. 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.

Wenn Sie den Serverendpunkt für HTTP v1 aktualisieren möchten, fügen Sie dem Endpunkt im Header Ihrer gesendeten Anfragen diese Elemente hinzu.

HTTP-Anfragen vor

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

XMPP-Anfragen vor

Legacy-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 das Admin SDK zum Senden von Nachrichten verwenden, wird das Token von der Bibliothek für Sie verarbeitet. 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 für das Dienstkonto
  • 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 umfassende Automatisierung des Autorisierungsablaufs sollten Sie ADC mit 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 die Anmeldedaten weder im ersten noch im zweiten Schritt ermittelt werden können, löst das System einen Fehler aus.

Das folgende Admin SDK-Codebeispiel 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 Shell-Sitzung. 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 Anmeldedaten für Dienstkonten 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 Auth-Bibliothek 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.

Wenn Sie Zugriff auf FCM gewähren möchten, fordern Sie den Umfang https://www.googleapis.com/auth/firebase.messaging an.

So fügen Sie einem HTTP-Anfrageheader das Zugriffstoken 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. Diese Änderungen sorgen vor allem dafür, dass Nachrichten richtig verarbeitet werden, wenn sie auf verschiedenen Clientplattformen empfangen werden. Außerdem bieten sie Ihnen zusätzliche Flexibilität, Nachrichtenfelder je nach 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 bisherigen 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. HTTP v1 bietet dagegen platformspezifische Schlüsselblöcke, die alle Unterschiede zwischen den Plattformen für den Entwickler explizit und 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 je nach Plattform 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: