Ihre Serverumgebung und FCM
Die Serverseite von Firebase Cloud Messaging besteht aus zwei Komponenten:
- Das von Google bereitgestellte FCM-Backend .
- Ihr App-Server oder eine andere vertrauenswürdige Serverumgebung, in der Ihre Serverlogik ausgeführt wird, z. B. Cloud Functions für Firebase oder andere von Google verwaltete Cloud-Umgebungen.
Ihr App-Server oder Ihre vertrauenswürdige Serverumgebung sendet Nachrichtenanforderungen an das FCM-Backend, das dann Nachrichten an Client-Apps weiterleitet, die auf den Geräten der Benutzer ausgeführt werden.
Anforderungen an die vertrauenswürdige Serverumgebung
Ihre App-Server-Umgebung muss die folgenden Kriterien erfüllen:
- Kann ordnungsgemäß formatierte Nachrichtenanfragen an das FCM-Backend senden.
- Kann Anfragen bearbeiten und mithilfe eines exponentiellen Backoffs erneut senden.
- Kann Server-Autorisierungsanmeldeinformationen und Client-Registrierungstokens sicher speichern.
- Für das XMPP-Protokoll (falls verwendet) muss der Server in der Lage sein, Nachrichten-IDs zu generieren, um jede von ihm gesendete Nachricht eindeutig zu identifizieren (das FCM-HTTP-Backend generiert Nachrichten-IDs und gibt sie in der Antwort zurück). XMPP-Nachrichten-IDs sollten pro Absender-ID eindeutig sein.
Auswahl einer Serveroption
Sie müssen sich für eine Art der Interaktion mit FCM-Servern entscheiden: entweder über das Firebase Admin SDK oder die Rohprotokolle. Aufgrund seiner Unterstützung für gängige Programmiersprachen und seiner praktischen Methoden zur Authentifizierung und Autorisierung ist das Firebase Admin SDK die empfohlene Methode.
Zu den Optionen für die Interaktion mit FCM-Servern gehören die folgenden:
- Das Firebase Admin SDK, das Node , Java , Python , C# und Go unterstützt.
- Die FCM HTTP v1 API , die aktuellste Protokolloption, mit sichererer Autorisierung und flexiblen plattformübergreifenden Messaging-Funktionen (das Firebase Admin SDK basiert auf diesem Protokoll und bietet alle inhärenten Vorteile). Da neue Funktionen normalerweise nur zur HTTP v1-API hinzugefügt werden, empfehlen wir für die meisten Anwendungsfälle die Verwendung dieser API.
- Das alte HTTP- Protokoll. Bei neuen Projekten wird dringend empfohlen, die HTTP-API FCM v1 anstelle des Legacy-Protokolls zu übernehmen.
- Das alte XMPP- Serverprotokoll. Bei neuen Projekten wird dringend empfohlen, die HTTP-API FCM v1 anstelle des Legacy-Protokolls zu übernehmen.
Firebase Admin SDK für FCM
Die Admin-FCM-API übernimmt die Authentifizierung beim Backend und erleichtert das Senden von Nachrichten und die Verwaltung von Themenabonnements. Mit dem Firebase Admin SDK können Sie:
- Senden Sie Nachrichten an einzelne Geräte
- Senden Sie Nachrichten an Themen und Bedingungsanweisungen, die einem oder mehreren Themen entsprechen.
- Geräte für Themen abonnieren und abmelden
- Erstellen Sie Nachrichtennutzlasten, die auf verschiedene Zielplattformen zugeschnitten sind
Das Admin Node.js SDK bietet Methoden zum Senden von Nachrichten an Gerätegruppen.
Informationen zum Einrichten des Firebase Admin SDK finden Sie unter Hinzufügen des Firebase Admin SDK zu Ihrem Server . Wenn Sie bereits über ein Firebase-Projekt verfügen, beginnen Sie mit „Add the SDK“ (SDK hinzufügen) . Stellen Sie außerdem sicher, dass Sie die Cloud Messagin API auf der Seite mit den Cloud Messaging-Einstellungen für Ihr Projekt aktivieren. Sobald das Firebase Admin SDK installiert ist, können Sie mit dem Schreiben der Logik zum Erstellen von Sendeanfragen beginnen.
FCM-Serverprotokolle
Derzeit stellt FCM diese Rohserverprotokolle bereit:
- FCM HTTP v1 API
- Legacy- HTTP-Protokoll
- Legacy -XMPP-Protokoll
Ihr App-Server kann diese Protokolle einzeln oder zusammen verwenden. Da es sich um die aktuellste und flexibelste Methode zum Senden von Nachrichten an mehrere Plattformen handelt, wird die FCM HTTP v1-API empfohlen, wo immer dies möglich ist. Wenn Ihre Anforderungen Upstream-Messaging von Geräten zum Server umfassen, müssen Sie das XMPP-Protokoll implementieren.
XMPP-Nachrichten unterscheiden sich von HTTP-Nachrichten in folgenden Punkten:
- Upstream-/Downstream-Nachrichten
- HTTP: Nur Downstream, Cloud-to-Device.
- XMPP: Upstream und Downstream (Gerät-zu-Cloud, Cloud-zu-Gerät).
- Messaging (synchron oder asynchron)
- HTTP: Synchron. App-Server senden Nachrichten als HTTP-POST-Anfragen und warten auf eine Antwort. Dieser Mechanismus ist synchron und verhindert, dass der Absender eine weitere Nachricht sendet, bis die Antwort eingegangen ist.
- XMPP: Asynchron. App-Server senden/empfangen Nachrichten an/von all ihren Geräten mit voller Leitungsgeschwindigkeit über dauerhafte XMPP-Verbindungen. Der XMPP-Verbindungsserver sendet asynchron Bestätigungs- oder Fehlerbenachrichtigungen (in Form spezieller ACK- und NACK-JSON-codierter XMPP-Nachrichten).
- JSON
- HTTP: JSON-Nachrichten, die als HTTP POST gesendet werden.
- XMPP: In XMPP-Nachrichten gekapselte JSON-Nachrichten.
- Klartext
- HTTP: Nur-Text-Nachrichten, die als HTTP POST gesendet werden.
- XMPP: Nicht unterstützt.
- Multicast-Downstream-Senden an mehrere Registrierungstoken.
- HTTP: Wird im JSON-Nachrichtenformat unterstützt.
- XMPP: Nicht unterstützt.
Implementierung des HTTP-Serverprotokolls
Um eine Nachricht zu senden, gibt der App-Server eine POST-Anfrage mit einem HTTP-Header und einem HTTP-Body bestehend aus JSON-Schlüssel-Wert-Paaren aus. Einzelheiten zu den Header- und Textoptionen finden Sie unter Build App Server Send Requests
Implementierung des XMPP-Serverprotokolls
Die JSON-Nutzlast für FCM-Nachrichten ähnelt dem HTTP-Protokoll, mit folgenden Ausnahmen:
- Es gibt keine Unterstützung für mehrere Empfänger.
- FCM fügt das Feld
message_id
hinzu, das erforderlich ist. Diese ID identifiziert die Nachricht eindeutig in einer XMPP-Verbindung. Das ACK oder NACK von FCM verwendet diemessage_id
, um eine Nachricht zu identifizieren, die von App-Servern an FCM gesendet wird. Daher ist es wichtig, dass diesemessage_id
nicht nur eindeutig ist (pro Absender-ID ), sondern immer vorhanden ist. - XMPP verwendet den Serverschlüssel, um eine dauerhafte Verbindung zu FCM zu autorisieren. Weitere Informationen finden Sie unter Sendeanfragen autorisieren .
Zusätzlich zu den regulären FCM-Nachrichten werden Kontrollnachrichten gesendet, die durch das Feld message_type
im JSON-Objekt angezeigt werden. Der Wert kann entweder „ack“, „nack“ oder „control“ sein (siehe Formate unten). Jede FCM-Nachricht mit einem unbekannten message_type
kann von Ihrem Server ignoriert werden.
Für jede Gerätenachricht, die Ihr App-Server von FCM empfängt, muss er eine ACK-Nachricht senden. Es muss niemals eine NACK-Nachricht gesendet werden. Wenn Sie für eine Nachricht keine Bestätigung senden, sendet FCM sie erneut, wenn das nächste Mal eine neue XMPP-Verbindung hergestellt wird, es sei denn, die Nachricht läuft zuerst ab.
FCM sendet außerdem eine ACK oder NACK für jede Server-zu-Gerät-Nachricht. Wenn Sie beides nicht erhalten, bedeutet das, dass die TCP-Verbindung mitten im Vorgang geschlossen wurde und Ihr Server die Nachrichten erneut senden muss. Weitere Informationen finden Sie unter Flusskontrolle .
Eine Liste aller Nachrichtenparameter finden Sie in der Protokollreferenz .
Anfrageformat
Nachricht mit Nutzlast – Benachrichtigungsnachricht
Hier ist eine XMPP-Strophe für eine Benachrichtigungsnachricht:
<message id=""> <gcm xmlns="google:mobile:data"> { "to":"REGISTRATION_ID", // "to" replaces "registration_ids" "notification": { "title": "Portugal vs. Denmark”, "body”: "5 to 1” }, "time_to_live":"600" } </gcm> </message>
Nachricht mit Nutzlast – Datennachricht
Hier ist eine XMPP-Strophe, die die JSON-Nachricht von einem App-Server an FCM enthält:
<message id=""> <gcm xmlns="google:mobile:data"> { "to":"REGISTRATION_ID", // "to" replaces "registration_ids" "message_id":"m-1366082849205" // new required field "data": { "hello":"world", } "time_to_live":"600", } </gcm> </message>
Antwortformat
Eine FCM-Antwort kann drei mögliche Formen haben. Die erste ist eine reguläre „Ack“-Nachricht. Wenn die Antwort jedoch einen Fehler enthält, kann die Nachricht zwei verschiedene Formen annehmen, die im Folgenden beschrieben werden.
ACK-Nachricht
Hier ist eine XMPP-Strophe, die die ACK/NACK-Nachricht von FCM an den App-Server enthält:
<message id=""> <gcm xmlns="google:mobile:data"> { "from":"REGID", "message_id":"m-1366082849205" "message_type":"ack" } </gcm> </message>
NACK-Nachricht
Ein NACK-Fehler ist eine reguläre XMPP-Nachricht, in der die Statusmeldung message_type
“ „nack“ lautet. Eine NACK-Nachricht enthält:
- Ein NACK-Fehlercode.
- Eine NACK-Fehlerbeschreibung.
Nachfolgend finden Sie einige Beispiele.
Schlechte Registrierung:
<message> <gcm xmlns="google:mobile:data"> { "message_type":"nack", "message_id":"msgId1", "from":"SomeInvalidRegistrationToken", "error":"BAD_REGISTRATION", "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId" } </gcm> </message>
Ungültiger JSON:
<message> <gcm xmlns="google:mobile:data"> { "message_type":"nack", "message_id":"msgId1", "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "error":"INVALID_JSON", "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc" } </gcm> </message>
Gerätenachrichtenrate überschritten:
<message id="..."> <gcm xmlns="google:mobile:data"> { "message_type":"nack", "message_id":"msgId1", "from":"REGID", "error":"DEVICE_MESSAGE_RATE_EXCEEDED", "error_description":"Downstream message rate exceeded for this registration id" } </gcm> </message>
Eine vollständige Liste der NACK-Fehlercodes finden Sie in der Serverreferenz . Sofern nicht anders angegeben, sollte eine NACKed-Nachricht nicht erneut versucht werden. Unerwartete NACK-Fehlercodes sollten genauso behandelt werden wie INTERNAL_SERVER_ERROR
.
Strophenfehler
In bestimmten Fällen kann es auch zu einem Zeilengruppenfehler kommen. Ein Zeilengruppenfehler enthält:
- Strophenfehlercode.
- Strophenfehlerbeschreibung (Freitext).
Zum Beispiel:
<message id="3" type="error" to="123456789@fcm.googleapis.com/ABC"> <gcm xmlns="google:mobile:data"> {"random": "text"} </gcm> <error code="400" type="modify"> <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"> InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n </text> </error> </message>
Kontrollnachrichten
In regelmäßigen Abständen muss FCM eine Verbindung schließen, um einen Lastausgleich durchzuführen. Bevor die Verbindung geschlossen wird, sendet FCM eine CONNECTION_DRAINING
Nachricht, um anzuzeigen, dass die Verbindung geleert wird und bald geschlossen wird. „Entleeren“ bezieht sich auf das Unterbrechen des Nachrichtenflusses, der in eine Verbindung gelangt, aber das Weiterlaufenlassen dessen, was sich bereits in der Pipeline befindet. Wenn Sie eine CONNECTION_DRAINING
-Nachricht erhalten, sollten Sie sofort damit beginnen, Nachrichten an eine andere FCM-Verbindung zu senden und bei Bedarf eine neue Verbindung zu öffnen. Sie sollten jedoch die ursprüngliche Verbindung offen halten und weiterhin Nachrichten empfangen, die möglicherweise über die Verbindung eingehen (und diese bestätigen) – FCM übernimmt die Initiierung eines Verbindungsabschlusses, wenn er bereit ist.
Die CONNECTION_DRAINING
-Nachricht sieht folgendermaßen aus:
<message> <data:gcm xmlns:data="google:mobile:data"> { "message_type":"control" "control_type":"CONNECTION_DRAINING" } </data:gcm> </message>
CONNECTION_DRAINING
ist derzeit der einzige unterstützte control_type
.
Ablaufsteuerung
Jede an FCM gesendete Nachricht erhält entweder eine ACK- oder eine NACK-Antwort. Nachrichten, die keine dieser Antworten erhalten haben, gelten als ausstehend. Wenn die Anzahl der ausstehenden Nachrichten 100 erreicht, sollte der App-Server aufhören, neue Nachrichten zu senden und darauf warten, dass FCM einige der vorhandenen ausstehenden Nachrichten bestätigt, wie in Abbildung 1 dargestellt:
Abbildung 1. Nachrichten-/Bestätigungsfluss.
Um umgekehrt eine Überlastung des App-Servers zu vermeiden, stoppt FCM das Senden, wenn zu viele unbestätigte Nachrichten vorliegen. Daher sollte der App-Server Upstream-Nachrichten, die von der Clientanwendung über FCM empfangen werden, so schnell wie möglich „ACKen“, um einen konstanten Fluss eingehender Nachrichten aufrechtzuerhalten. Das oben genannte Limit für ausstehende Nachrichten gilt nicht für diese ACKs. Auch wenn die Anzahl der ausstehenden Nachrichten 100 erreicht, sollte der App-Server weiterhin ACKs für vom FCM empfangene Nachrichten senden, um die Blockierung der Zustellung neuer Upstream-Nachrichten zu vermeiden.
ACKs sind nur im Kontext einer Verbindung gültig. Wenn die Verbindung geschlossen wird, bevor eine Nachricht bestätigt werden kann, sollte der App-Server warten, bis FCM die Upstream-Nachricht erneut sendet, bevor er sie erneut bestätigt. Ebenso sollten alle ausstehenden Nachrichten, für die vor dem Schließen der Verbindung kein ACK/NACK vom FCM empfangen wurde, erneut gesendet werden.