Specyfikacja protokołu dla https.onCall

Wyzwalacz https.onCall dla Cloud Functions to wyzwalacz HTTPS z określonym formatem żądania i odpowiedzi. W tej sekcji przedstawiono specyfikację formatów żądań i odpowiedzi HTTPS używanych przez zestawy SDK klienta do implementowania interfejsu API. Te informacje mogą być dla Ciebie przydatne, jeśli nie można spełnić Twoich wymagań przy użyciu platform Android, Apple lub internetowych zestawów SDK.

Format żądania: nagłówki

Żądanie HTTP do wywoływalnego punktu końcowego wyzwalacza musi mieć postać POST z następującymi nagłówkami:

  • Wymagane: Content-Type: application/json
    • Opcjonalnie ; charset=utf-8 jest dozwolony.
  • Opcjonalnie: Authorization: Bearer <token>
    • Token identyfikatora użytkownika uwierzytelniania Firebase dla zalogowanego użytkownika wysyłającego żądanie. Backend automatycznie weryfikuje ten token i udostępnia go w context obsługi. Jeżeli token jest nieprawidłowy, żądanie zostaje odrzucone.
  • Opcjonalnie: Firebase-Instance-ID-Token: <iid>
    • Token rejestracji FCM z pakietu SDK klienta Firebase. To musi być ciąg. Jest to dostępne w context obsługi. Służy do targetowania powiadomień push.
  • Opcjonalnie: X-Firebase-AppCheck: <token>
    • Token sprawdzania aplikacji Firebase dostarczony przez aplikację kliencką wysyłającą żądanie. Backend automatycznie weryfikuje ten token i dekoduje go, wstrzykując identyfikator appId w context obsługi. Jeżeli nie można zweryfikować tokena, żądanie zostaje odrzucone. (Dostępne dla SDK >=3.14.0)

Jeśli uwzględnione zostaną inne nagłówki, żądanie zostanie odrzucone, zgodnie z opisem w dokumentacji odpowiedzi poniżej.

Uwaga: w klientach JavaScript te żądania wyzwalają inspekcję wstępną CORS OPTIONS , ponieważ:

Wywoływalny wyzwalacz automatycznie obsługuje te żądania OPTIONS .

Treść żądania

Treść żądania HTTP powinna być obiektem JSON zawierającym dowolne z poniższych pól:

  • Wymagane: data - Argument przekazywany do funkcji. Może to być dowolna prawidłowa wartość JSON. Jest to automatycznie dekodowane do natywnych typów JavaScript zgodnie z formatem serializacji opisanym poniżej.

Jeśli w żądaniu znajdują się inne pola, backend uzna żądanie za zniekształcone i zostanie odrzucone.

Format odpowiedzi: kody statusu

Istnieje kilka przypadków, w których w odpowiedzi mogą pojawić się różne kody stanu HTTP i ciągi kodów stanu w przypadku błędów .

  1. W przypadku błędu HTTP przed wywołaniem wyzwalacza client odpowiedź nie jest obsługiwana jako funkcja klienta. Na przykład, jeśli klient spróbuje wywołać nieistniejącą funkcję, otrzyma odpowiedź 404 Not Found .

  2. Jeśli wyzwalacz klienta zostanie wywołany, ale żądanie ma niewłaściwy format, na przykład nie jest JSON, zawiera nieprawidłowe pola lub brakuje mu pola data , żądanie zostaje odrzucone z komunikatem 400 Bad Request i kodem błędu INVALID_ARGUMENT .

  3. Jeżeli token autoryzacji podany w żądaniu jest nieprawidłowy, żądanie zostaje odrzucone z 401 Unauthorized i kodem błędu UNAUTHENTICATED .

  4. Jeśli token rejestracyjny FCM dostarczony w żądaniu jest nieprawidłowy, zachowanie jest niezdefiniowane. Token nie jest sprawdzany przy każdym żądaniu, z wyjątkiem sytuacji, gdy służy do wysyłania powiadomienia push z FCM.

  5. Jeśli wywołany wyzwalacz zakończy się niepowodzeniem z powodu nieobsłużonego wyjątku lub zwróci nieudaną obietnicę, żądanie zostanie odrzucone z komunikatem 500 Internal Server Error i kodem błędu INTERNAL . Zapobiega to przypadkowemu ujawnieniu błędów kodowania użytkownikom końcowym.

  6. Jeśli wywołana zostanie funkcja wywoływalna i zwróci jawny warunek błędu przy użyciu interfejsu API udostępnionego dla funkcji wywoływalnych, żądanie zakończy się niepowodzeniem. Zwrócony kod stanu HTTP opiera się na oficjalnym mapowaniu stanu błędu na status HTTP, zgodnie z definicją w code.proto . Konkretny kod błędu, komunikat i zwrócone szczegóły są zakodowane w treści odpowiedzi, jak opisano poniżej. Oznacza to, że jeśli funkcja zwróci jawny błąd o statusie OK , to odpowiedź ma status 200 OK , ale w odpowiedzi ustawione jest pole error .

  7. Jeśli wyzwalacz klienta zakończy się pomyślnie, status odpowiedzi to 200 OK .

Format odpowiedzi: nagłówki

Odpowiedź zawiera następujące nagłówki:

  • Content-Type: application/json
  • Opcjonalnie ; charset=utf-8 jest dozwolony.

Treść odpowiedzi

Odpowiedź z punktu końcowego klienta jest zawsze obiektem JSON. Zawiera co najmniej result lub error wraz z opcjonalnymi polami. Jeśli odpowiedź nie jest obiektem JSON lub nie zawiera data lub error , pakiet SDK klienta powinien potraktować żądanie jako zakończone niepowodzeniem i wyświetlić kod błędu Google INTERNAL (13) .

  • error - Jeżeli to pole jest obecne, żądanie uznaje się za nieudane, niezależnie od kodu statusu HTTP i tego, czy obecne są również data . Wartość tego pola powinna być obiektem JSON w standardowym formacie mapowania Google Cloud HTTP dla błędów, z polami dotyczącymi status , message i (opcjonalnie) details . Pole code nie jest uwzględniane. Jeżeli pole status jest nieustawione lub ma nieprawidłową wartość, klient powinien potraktować status jako INTERNAL , zgodnie z code.proto . Jeśli obecne są details , są one uwzględniane we wszelkich informacjach o użytkowniku dołączonych do błędu w pakiecie SDK klienta, jeśli ma to zastosowanie.
    Uwaga: pole details jest wartością podaną przez użytkownika. Niekoniecznie jest to lista wartości wpisanych według typu proto, jak w formacie Google Status .
  • result – Wartość zwracana przez funkcję. Może to być dowolna prawidłowa wartość JSON. Zestaw SDK funkcji Firebase automatycznie koduje wartość zwróconą przez użytkownika w tym formacie JSON. Zestawy SDK klienta automatycznie dekodują te parametry na typy natywne zgodnie z formatem serializacji opisanym poniżej.

Jeśli obecne są inne pola, należy je zignorować.

Serializacja

Format serializacji dla dowolnych ładunków danych jest taki sam zarówno w przypadku żądania, jak i odpowiedzi.

Aby zapewnić spójność platformy, są one kodowane w formacie JSON tak, jakby były wartością pola Any w buforze protokołu proto3, przy użyciu standardowego mapowania JSON . Wartości typów prostych, takich jak null , int , double lub string , są kodowane bezpośrednio i nie obejmują ich jawnego typu. Zatem float i double są kodowane w ten sam sposób i możesz nie wiedzieć, co zostanie odebrane po drugiej stronie połączenia. W przypadku typów, które nie są natywne dla JSON, używane jest wpisane kodowanie proto3 dla wartości. Aby uzyskać więcej informacji, zapoznaj się z dokumentacją dotyczącą dowolnego kodowania JSON .

Dozwolone są następujące typy:

  • zero null
  • int (ze znakiem lub bez znaku, do 32 bitów) - np. 3 lub -30 .
  • float - np. 3.14
  • podwójne - np. 3.14
  • wartość logiczna – true lub false
  • ciąg znaków - np. "hello world"
  • mapa - np. {"x": 3}
  • lista - np. [1, 2, 3]
  • długi (ze znakiem lub bez znaku, do 64 bitów) - [szczegóły poniżej]

Wartości NaN i Infinity dla float i double nie są obsługiwane.

Należy pamiętać, że long jest typem specjalnym, który zwykle nie jest dozwolony w JSON, ale jest objęty specyfikacją proto3. Na przykład są one kodowane jako:

długi

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

długi bez znaku

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

Ogólnie rzecz biorąc, klucz @type należy uważać za zarezerwowany i nie używać go do przekazywanych map.

Ponieważ typ nie jest określony dla typów prostych, niektóre wartości zmienią typ po przejściu przez przewód. Przekazany float staje się double . short staje się int i tak dalej. W systemie Android w przypadku wartości list obsługiwane są zarówno List , jak i JSONArray . W takich przypadkach przekazanie JSONArray zwróci List .

Jeśli mapa z nieznanym polem @type zostanie deserializowana, pozostanie jako mapa. Dzięki temu programiści mogą dodawać pola z nowymi typami do zwracanych wartości bez psucia starszych klientów.

Próbki kodu

Przykłady w tej sekcji ilustrują sposób kodowania następujących elementów:

  • Przykład callable.call w Swift
  • Skuteczna odpowiedź na połączenie
  • Odpowiedź na niepowodzenie połączenia

Przykład Callable.call w Swift do kodowania

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

Nagłówek żądania:

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

Treść żądania:

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

Odpowiedź na kodowanie

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

Nagłówek pomyślnej odpowiedzi:

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

Treść pomyślnej odpowiedzi:

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

Odpowiedź na błąd kodowania

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

Nagłówek nieudanej odpowiedzi:

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

Treść odpowiedzi nie powiodła się:

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