Specyfikacja protokołu dla https.onCall

Aktywator https.onCall dla Cloud Functions to aktywator HTTPS z określonym formatem żądania i odpowiedzi. W tej sekcji znajdziesz specyfikację formatów żądań i odpowiedzi HTTPS używanych przez pakiety SDK klienta do implementowania interfejsu API. Te informacje mogą być przydatne, jeśli nie możesz spełnić wymagań za pomocą pakietów SDK dla Androida, Apple lub internetu.

Format żądania: nagłówki

Żądanie HTTP do punktu końcowego aktywatora, które można wywołać, musi mieć typ POST z następującymi nagłówkami:

  • Wymagane: Content-Type: application/json
    • Dozwolona jest opcjonalna wartość ; charset=utf-8.
  • Opcjonalnie: Authorization: Bearer <token>
    • Firebase Authentication token identyfikatora użytkownika, który wysyła żądanie. Backend automatycznie weryfikuje ten token i udostępnia go w context modułu obsługi. Jeśli token jest nieprawidłowy, żądanie zostaje odrzucone.
  • Opcjonalnie: Firebase-Instance-ID-Token: <iid>
    • Token rejestracji FCM z pakietu SDK klienta Firebase. Musi to być ciąg znaków. Jest ona dostępna w context. Służy do kierowania powiadomień push.
  • Opcjonalnie: X-Firebase-AppCheck: <token>
    • Token Sprawdzania aplikacji Firebase dostarczony przez aplikację klienta przesyłającą żądanie. Backend automatycznie weryfikuje ten token i dekoduje go, wstrzykując appId do context w obsługowniku. Jeśli nie uda się zweryfikować tokena, prośba zostanie odrzucona. (dostępne w pakiecie SDK w wersji ≥ 3.14.0)

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

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

Aktywator z możliwością wywołania automatycznie obsługuje te OPTIONS żądania.

Treść żądania

Treść żądania HTTP powinna być obiektem JSON z jednym z tych pól:

  • Wymagane: data – argument przekazany do funkcji. Może to być dowolna prawidłowa wartość JSON. Jest on automatycznie dekodowany na natywne typy JavaScript zgodnie z opisanym poniżej formatem serializacji.

Jeśli w żądaniu są inne pola, backend uzna je za źle sformułowane i odrzuci.

Format odpowiedzi: kody stanu

Istnieje kilka przypadków, w których w odpowiedzi mogą występować różne kody stanu HTTP i kod stanu ciągu znaków dla błędów.

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

  2. Jeśli wywołany zostanie wyzwalacz klienta, ale żądanie ma nieprawidłowy format (np. nie jest w formacie JSON, zawiera nieprawidłowe pola lub brakuje pola data), żądanie jest odrzucane z wartością 400 Bad Request i kodem błędu INVALID_ARGUMENT.

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

  4. Jeśli token rejestracji FCM podany w żądaniu jest nieprawidłowy, zachowanie jest nieokreślone. Token nie jest sprawdzany w każdym żądaniu z wyjątkiem sytuacji, gdy jest on używany do wysyłania powiadomień push w FCM.

  5. Jeśli wywołany wyzwalacz funkcji wywoływalnej zwraca błąd z nieobsługiwanym wyjątkiem lub zwraca obietnicę z błędem, żądanie jest odrzucane z wartością 500 Internal Server Error i kodem błędu INTERNAL. Zapobiega to przypadkowemu ujawnieniu błędów w kodzie użytkownikom.

  6. Jeśli wywoływana funkcja zostanie wywołana i zwróci jawny stan błędu za pomocą interfejsu API udostępnionego dla funkcji wywoływalnych, żądanie się nie powiedzie. Zwrócony kod stanu HTTP jest oparty na oficjalnym mapowaniu stanu błędu na stan HTTP zgodnie z definicją w pliku code.proto. W treści odpowiedzi kod błędu, komunikat i szczegóły są zakodowane w sposób podany poniżej. Oznacza to, że jeśli funkcja zwróci jawny błąd o stanie OK, odpowiedź będzie miała stan 200 OK, ale w odpowiedzi będzie ustawione pole error.

  7. Jeśli wywołanie klienta się powiedzie, stan odpowiedzi będzie miał wartość 200 OK.

Format odpowiedzi: nagłówki

Odpowiedź ma te nagłówki:

  • Content-Type: application/json
  • Opcjonalny składnik ; charset=utf-8 jest dozwolony.

Treść odpowiedzi

Odpowiedź z punktu końcowego klienta to zawsze obiekt JSON. Zawiera ona co najmniej result lub error oraz wszystkie pola opcjonalne. Jeśli odpowiedź nie jest obiektem JSON lub nie zawiera atrybutów data ani error, pakiet SDK klienta powinien potraktować żądanie jako nieudane z kodem błędu Google INTERNAL (13).

  • error – jeśli to pole jest obecne, żądanie jest uważane za nieudane niezależnie od kodu stanu HTTP lub obecności pola data. W przypadku błędów wartość tego pola powinna być obiektem JSON w standardowym formacie mapowania HTTP Google Cloud, z polami status, message i (opcjonalnie) details. Pole code nie powinno zostać uwzględnione. Jeśli pole status jest nieskonfigurowana lub ma nieprawidłową wartość, klient powinien traktować stan jako INTERNAL zgodnie z zasadą code.proto. Jeśli występuje wartość details, jest ona uwzględniana w informacjach o użytkowniku dołączonych do błędu w pakiecie SDK klienta (w stosownych przypadkach).
    Uwaga: pole details jest wartością podaną przez użytkownika. Nie musi to być lista wartości posortowana według klucza proto typu, jak w formacie Google Status.
  • result – wartość zwrócona przez funkcję. Może to być dowolna prawidłowa wartość JSON. Pakiet SDK firebase-functions automatycznie koduje wartość zwracaną przez użytkownika do tego formatu JSON. Pakiety SDK klienta automatycznie dekodują te parametry na typy natywne zgodnie z opisanym poniżej formatem serializacji.

Jeśli występują inne pola, należy je zignorować.

Serializacja

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

Aby zachować spójność na platformach, 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 prostych typów, np. null, int, double lub string, są kodowane bezpośrednio i nie zawierają ich typu. Z tego powodu znaki float i double są kodowane w ten sam sposób, więc nie wiadomo, który z nich zostanie odebrany po drugiej stronie połączenia. W przypadku typów, które nie są natywne dla JSON, do wartości używane jest kodowanie proto3. Więcej informacji znajdziesz w dokumentacji dotyczącej kodowania dowolnego formatu JSON.

Dozwolone są te typy:

  • null – null
  • int (z sygnaturą lub bez, do 32 bitów) – np. 3 lub -30.
  • float – np. 3.14
  • podwójny – np. 3.14
  • wartość logiczna – true lub false
  • ciąg znaków, np. "hello world"
  • map<string, any=""> – np. {"x": 3}</string,>
  • lista – np. [1, 2, 3]
  • długi (podpisany lub niepodpisany, do 64 bitów) – [szczegóły znajdziesz poniżej]

Wartości NaNInfinity w przypadku właściwości floatdouble nie są obsługiwane.

Pamiętaj, że long to typ specjalny, który zwykle nie jest dozwolony w formacie JSON, ale jest objęty specyfikacją proto3. Na przykład są one zakodowane w taki sposób:

Liczba długa

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

długi bez znaku

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

Ogólnie klucz @type powinien być uważany za zarezerwowany i nie powinien być używany w przekazywanych mapach.

Jako że typ nie jest określony dla prostych typów, niektóre wartości po użyciu przewodu zmienią typ. Przekazana wartość float staje się elementem double. Typ short zmienia się w int itd. W Androidzie w przypadku wartości listy obsługiwane są zarówno List, jak i JSONArray. W takich przypadkach przekazanie tablicy JSONArray spowoduje uzyskanie wartości List.

Jeśli deserializacja mapy z nieznanym polem @type zakończy się powodzeniem, mapa pozostanie w postaci mapy. Umożliwia to deweloperom dodawanie pól z nowymi typami do wartości zwracanych bez zakłócania działania starszych klientów.

Przykładowe fragmenty kodu

Przykłady w tej sekcji pokazują, jak zakodować następujące dane:

  • Przykład callable.call w języku Swift
  • odpowiedź na wywołanie,
  • odpowiedź o niepowodzenie wywołania;

Przykład funkcji callable.call w języku Swift do zakodowania

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ź do zakodowania

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

Nagłówek odpowiedzi zakończonej powodzeniem:

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

Treść odpowiedzi w przypadku powodzenia:

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

Błąd odpowiedzi na kodowanie

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

Nagłówek odpowiedzi z błędem:

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

Treść odpowiedzi:

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