Protokollspezifikation für https.onCall

Ein https.onCall Trigger für Cloud Functions ist ein HTTPS-Trigger mit einem bestimmten Format für die Anfrage und Antwort. Dieser Abschnitt enthält eine Spezifikation für die HTTPS-Anforderungs- und Antwortformate, die von den Client-SDKs zur Implementierung der API verwendet werden. Diese Informationen können für Sie hilfreich sein, wenn Ihre Anforderungen mit den Android-, Apple-Plattformen oder Web-SDKs nicht erfüllt werden können.

Anforderungsformat: Header

Die HTTP-Anfrage an einen aufrufbaren Trigger-Endpunkt muss ein POST mit den folgenden Headern sein:

  • Erforderlich: Content-Type: application/json
    • Ein optionales ; charset=utf-8 ist erlaubt.
  • Optional: Authorization: Bearer <token>
    • Ein Firebase-Authentifizierungs-Benutzer-ID-Token für den angemeldeten Benutzer, der die Anfrage stellt. Das Backend überprüft dieses Token automatisch und stellt es im context des Handlers zur Verfügung. Wenn das Token ungültig ist, wird die Anfrage abgelehnt.
  • Optional: Firebase-Instance-ID-Token: <iid>
    • Das FCM-Registrierungstoken aus dem Firebase-Client-SDK. Dies muss eine Zeichenfolge sein. Dies ist im context des Handlers verfügbar. Es wird für gezielte Push-Benachrichtigungen verwendet.
  • Optional: X-Firebase-AppCheck: <token>
    • Das Firebase App Check-Token, das von der Client-App bereitgestellt wird, die die Anfrage stellt. Das Backend überprüft dieses Token automatisch und dekodiert es, indem es die appId in den context des Handlers einfügt. Wenn das Token nicht verifiziert werden kann, wird die Anfrage abgelehnt. (Verfügbar für SDK >=3.14.0)

Wenn andere Header enthalten sind, wird die Anfrage abgelehnt, wie in der Antwortdokumentation unten beschrieben.

Hinweis: In JavaScript-Clients lösen diese Anfragen einen CORS OPTIONS Preflight aus, weil:

  • application/json ist nicht zulässig. Es muss text/plain oder application/x-www-form-urlencoded sein.
  • Der Authorization Header ist kein CORS-sicherer Request-Header .
  • Andere Header sind ebenfalls nicht zulässig.

Der aufrufbare Trigger verarbeitet diese OPTIONS Anfragen automatisch.

Anforderungstext

Der Hauptteil der HTTP-Anfrage sollte ein JSON-Objekt mit einem der folgenden Felder sein:

  • Erforderlich: data – Das an die Funktion übergebene Argument. Dies kann ein beliebiger gültiger JSON-Wert sein. Dies wird gemäß dem unten beschriebenen Serialisierungsformat automatisch in native JavaScript-Typen dekodiert.

Wenn in der Anfrage weitere Felder vorhanden sind, betrachtet das Backend die Anfrage als fehlerhaft und wird abgelehnt.

Antwortformat: Statuscodes

Es gibt mehrere Fälle, die zu unterschiedlichen HTTP-Statuscodes und String-Statuscodes für Fehler in der Antwort führen können.

  1. Tritt ein HTTP-Fehler auf, bevor der client Trigger aufgerufen wird, wird die Antwort nicht als Client-Funktion behandelt. Wenn ein Client beispielsweise versucht, eine nicht vorhandene Funktion aufzurufen, erhält er die Antwort 404 Not Found .

  2. Wenn der Client-Trigger aufgerufen wird, die Anfrage jedoch im falschen Format vorliegt, z. B. weil sie kein JSON ist, ungültige Felder enthält oder das data fehlt, wird die Anfrage mit 400 Bad Request und dem Fehlercode INVALID_ARGUMENT abgelehnt.

  3. Wenn das in der Anfrage angegebene Authentifizierungstoken ungültig ist, wird die Anfrage mit 401 Unauthorized und dem Fehlercode UNAUTHENTICATED abgelehnt.

  4. Wenn das in der Anfrage angegebene FCM-Registrierungstoken ungültig ist, ist das Verhalten undefiniert. Das Token wird nicht bei jeder Anfrage überprüft, außer wenn es zum Senden einer Push-Benachrichtigung mit FCM verwendet wird.

  5. Wenn der aufrufbare Trigger aufgerufen wird, aber mit einer nicht behandelten Ausnahme fehlschlägt oder ein fehlgeschlagenes Versprechen zurückgibt, wird die Anforderung mit 500 Internal Server Error und dem Fehlercode INTERNAL abgelehnt. Dies verhindert, dass Codierungsfehler versehentlich Endbenutzern offengelegt werden.

  6. Wenn die aufrufbare Funktion aufgerufen wird und mithilfe der für aufrufbare Funktionen bereitgestellten API eine explizite Fehlerbedingung zurückgibt, schlägt die Anforderung fehl. Der zurückgegebene HTTP-Statuscode basiert auf der offiziellen Zuordnung des Fehlerstatus zum HTTP-Status, wie in code.proto definiert. Der spezifische Fehlercode, die zurückgegebene Meldung und die zurückgegebenen Details werden wie unten beschrieben im Antworttext codiert. Das heißt, wenn die Funktion einen expliziten Fehler mit dem Status OK zurückgibt, hat die Antwort den Status 200 OK , aber das error ist in der Antwort gesetzt.

  7. Wenn der Client-Trigger erfolgreich ist, lautet der Antwortstatus 200 OK .

Antwortformat: Header

Die Antwort hat die folgenden Header:

  • Content-Type: application/json
  • Ein optionales ; charset=utf-8 ist erlaubt.

Antwortkörper

Die Antwort von einem Client-Endpunkt ist immer ein JSON-Objekt. Es enthält mindestens entweder result oder error sowie alle optionalen Felder. Wenn die Antwort kein JSON-Objekt ist oder keine data oder error enthält, sollte das Client-SDK die Anfrage als fehlgeschlagen mit dem Google-Fehlercode INTERNAL (13) behandeln.

  • error – Wenn dieses Feld vorhanden ist, gilt die Anfrage als fehlgeschlagen, unabhängig vom HTTP-Statuscode oder davon, ob auch data vorhanden sind. Der Wert dieses Felds sollte ein JSON-Objekt im standardmäßigen Google Cloud HTTP Mapping- Format für Fehler sein, mit Feldern für status , message und (optional) details . Das code darf nicht enthalten sein. Wenn das status nicht gesetzt ist oder einen ungültigen Wert hat, sollte der Client den Status gemäß code.proto als INTERNAL behandeln. Wenn details vorhanden sind, sind diese gegebenenfalls in allen Benutzerinformationen enthalten, die dem Fehler im Client-SDK beigefügt sind.
    Hinweis: Das details hier ist ein vom Benutzer bereitgestellter Wert. Es handelt sich nicht unbedingt um eine nach Prototyptyp verschlüsselte Werteliste wie im Google- Status .
  • result – Der von der Funktion zurückgegebene Wert. Dies kann ein beliebiger gültiger JSON-Wert sein. Das Firebase-Functions SDK kodiert den vom Benutzer zurückgegebenen Wert automatisch in dieses JSON-Format. Die Client-SDKs dekodieren diese Parameter automatisch in native Typen gemäß dem unten beschriebenen Serialisierungsformat.

Wenn andere Felder vorhanden sind, sollten diese ignoriert werden.

Serialisierung

Das Serialisierungsformat für beliebige Datennutzlasten ist für die Anfrage und die Antwort dasselbe.

Aus Gründen der Plattformkonsistenz werden diese in JSON codiert, als wären sie der Wert eines Any Felds in einem Proto3-Protokollpuffer, wobei die Standard-JSON-Zuordnung verwendet wird. Werte einfacher Typen wie null , int , double oder string werden direkt codiert und enthalten nicht ihren expliziten Typ. Daher werden float und double auf die gleiche Weise codiert, und Sie wissen möglicherweise nicht, was am anderen Ende des Anrufs empfangen wird. Für Typen, die nicht JSON-nativ sind, wird die typisierte Proto3-Kodierung für den Wert verwendet. Weitere Informationen finden Sie in der Dokumentation zu Beliebige JSON-Kodierung .

Folgende Typen sind erlaubt:

  • null - null
  • int (mit oder ohne Vorzeichen, bis zu 32 Bit) – z. B. 3 oder -30 .
  • float - zB 3.14
  • doppelt - zB 3.14
  • boolean – true oder false
  • Zeichenfolge – z. B. "hello world"
  • Karte - zB {"x": 3}
  • Liste - zB [1, 2, 3]
  • lang (mit oder ohne Vorzeichen, bis zu 64 Bit) – [Einzelheiten siehe unten]

NaN und Infinity Werte für float und double werden nicht unterstützt.

Beachten Sie, dass long ein spezieller Typ ist, der normalerweise in JSON nicht zulässig ist, aber von der Proto3-Spezifikation abgedeckt wird. Diese werden beispielsweise wie folgt kodiert:

lang

{
    '@type': 'type.googleapis.com/google.protobuf.Int64Value',
    'value': '-123456789123456'
}

unsigniert lang

{
    '@type': 'type.googleapis.com/google.protobuf.UInt64Value',
    'value': '123456789123456'
}

Im Allgemeinen sollte der @type Schlüssel als reserviert betrachtet und nicht für übergebene Karten verwendet werden.

Da der Typ für einfache Typen nicht angegeben ist, ändern einige Werte ihren Typ, nachdem sie über die Verbindung übertragen wurden. Ein übergebener float wird zu einem double . Ein short wird zu einem int und so weiter. In Android werden sowohl List als auch JSONArray für Listenwerte unterstützt. In diesen Fällen führt die Übergabe eines JSONArray zu einer List .

Wenn eine Karte mit einem unbekannten @type Feld deserialisiert wird, bleibt sie als Karte übrig. Dadurch können Entwickler Felder mit neuen Typen zu ihren Rückgabewerten hinzufügen, ohne ältere Clients zu beschädigen.

Codebeispiele

Die Beispiele in diesem Abschnitt veranschaulichen, wie Folgendes codiert wird:

  • Ein callable.call-Beispiel in Swift
  • Eine Erfolgsantwort für den Anruf
  • Eine Fehlerantwort für den Anruf

Callable.call-Beispiel in Swift zum Codieren

callable.call([
    "aString": "some string",
    "anInt": 57,
    "aFloat": 1.23,
    "aLong": -123456789123456 as Int64
])

Anforderungsheader:

Method: POST
Content-Type: application/json; charset=utf-8
Authorization: Bearer some-auth-token
Firebase-Instance-ID-Token: some-iid-token

Anfragetext:

{
    "data": {
        "aString": "some string",
        "anInt": 57,
        "aFloat": 1.23,
        "aLong": {
            "@type": "type.googleapis.com/google.protobuf.Int64Value",
            "value": "-123456789123456"
        }
    }
}

Antwort zum Kodieren

return {
    "aString": "some string",
    "anInt": 57,
    "aFloat": 1.23
};

Erfolgreicher Antwortheader:

200 OK
Content-Type: application/json; charset=utf-8

Erfolgreiches Antwortgremium:

{
    "response": {
        "aString": "some string",
        "anInt": 57,
        "aFloat": 1.23
    }
}

Fehlerantwort bei der Codierung

throw new HttpsError("unauthenticated", "Request had invalid credentials.", {
  "some-key": "some-value"
});

Header der fehlgeschlagenen Antwort:

401 UNAUTHENTICATED
Content-Type: application/json; charset=utf-8

Antworttext fehlgeschlagen:

{
    "error": {
        "message": "Request had invalid credentials.",
        "status": "UNAUTHENTICATED",
        "details": {
            "some-key": "some-value"
        }
    }
}