Specyfikacja protokołu dla https.onCall

Aktywator https.onCall dla Cloud Functions to aktywator HTTPS z tagiem określonego formatu żądania i odpowiedzi. W tej sekcji znajdziesz specyfikacja formatów żądań i odpowiedzi HTTPS używanych przez pakiety SDK klienta aby wdrożyć ten interfejs API. Te informacje mogą być przydatne, jeśli Twoje wymagania których nie można zrealizować za pomocą platform Androida i Apple ani internetowych pakietów SDK.

Format żądania: nagłówki

Żądanie HTTP do punktu końcowego aktywatora, które można wywołać, musi być typu POST z parametrem następujące nagłówki:

  • Wymagane: Content-Type: application/json
    • Dozwolona jest opcjonalna wartość ; charset=utf-8.
  • Opcjonalnie: Authorization: Bearer <token>
    • Token identyfikatora uwierzytelniania Firebase dla zalogowanego użytkownika wysyłającego żądanie. Backend automatycznie weryfikuje ten token i udostępnia go w context modułu obsługi. Jeśli token jest nieprawidłowy, żądanie jest odrzucane.
  • Opcjonalnie: Firebase-Instance-ID-Token: <iid>
    • Token rejestracji FCM z pakietu SDK klienta Firebase. Musi to być ciąg znaków. Te dane są dostępne w context modułu obsługi. Służy do kierowania na powiadomienia push.
  • Opcjonalnie: X-Firebase-AppCheck: <token>
    • Token Sprawdzania aplikacji Firebase udostępniony przez aplikację kliencką, która tworzy użytkownika. Backend automatycznie weryfikuje token i dekoduje go, wstrzykiwanie elementu appId w elemencie context modułu obsługi. Jeśli tokenem nie może być zostanie odrzucona. (Dostępne w przypadku SDK w wersji 3.14.0 lub nowszej).

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

Uwaga: w klientach JavaScriptu te żądania aktywują proces wstępny 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 dowolnym 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 występują inne pola, backend uznaje żądanie za uszkodzone i odrzuca je.

Format odpowiedzi: kody stanu

Istnieje kilka sytuacji, w których mogą wystąpić odmienne kody stanu HTTP i kody stanu ciągów znaków dla błędów w odpowiedzi.

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

  2. Jeśli aktywator klienta zostanie wywołany, ale żądanie ma nieprawidłowy format – na przykład nie jest w formacie JSON, zawiera nieprawidłowe pola lub brakuje pola data, żądanie zostanie odrzucone przy użyciu 400 Bad Request z kodem błędu INVALID_ARGUMENT.

  3. Jeśli token uwierzytelniania podany w żądaniu jest nieprawidłowy, żądanie jest odrzucane z użyciem 401 Unauthorized z kodem błędu UNAUTHENTICATED.

  4. Jeśli token rejestracji FCM podany w żądaniu jest nieprawidłowy, działanie jest niezdefiniowane. 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ływany aktywator jest wywoływany, ale kończy się niepowodzeniem z powodu nieobsłużonego wyjątku lub zwrócono nieudaną obietnicę, żądanie zostanie odrzucone z kodem 500 Internal Server Error z kodem błędu INTERNAL. Zapobiega to przypadkowemu ujawnieniu użytkownikom błędów kodowania.

  6. Żądanie nie zostanie zrealizowane, jeśli nastąpi wywołanie funkcji, która zwróci jawny warunek błędu za pomocą interfejsu API udostępnionego dla funkcji możliwych do wywołania. Zwracany kod stanu HTTP opiera się na oficjalnym zmapowaniu stanu błędu na stan HTTP, zgodnie z definicją w pliku code.proto. Konkretny kod błędu, komunikat i zwracane szczegóły są zakodowane w treści odpowiedzi w sposób opisany poniżej. Oznacza to, że jeśli funkcja zwraca jawny błąd w stanie OK, odpowiedź ma stan 200 OK, ale w odpowiedzi ustawiono pole error.

  7. Jeśli reguła klienta zadziała, odpowiedź będzie miała stan 200 OK.

Format odpowiedzi: nagłówki

Odpowiedź ma te nagłówki:

  • Content-Type: application/json
  • Dozwolona jest opcjonalna wartość ; charset=utf-8.

Treść odpowiedzi

Odpowiedź z punktu końcowego klienta jest zawsze obiektem JSON. Jest to minimum zawiera result lub error oraz wszystkie pola opcjonalne. Jeśli nie jest obiektem JSON ani nie zawiera data ani error, Pakiet SDK klienta powinien traktować żądanie jako nieudane z kodem błędu Google INTERNAL (13).

  • error – jeśli to pole jest obecne, żądanie jest uznawane za nieudane niezależnie od kodu stanu HTTP i tego, czy występuje też 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 details, jest on (w stosownych przypadkach) zawarty w informacjach o użytkowniku dołączonym do błędu w pakiecie SDK klienta.
    Uwaga: pole details jest wartością podaną przez użytkownika. Nie musi to być lista wartości klucz-wartość według typu proto, jak w formacie Status Google.
  • result – wartość zwracana przez funkcję. Może to być dowolna prawidłowa wartość JSON. Pakiet SDK firebase-functions automatycznie koduje wartość zwracaną przez użytkownika w tym formacie 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 dla żądania, jak i odpowiedzi.

Aby zapewnić spójność platformy, są one zakodowane w formacie JSON, tak jakby były to wartość pola Any w buforze protokołu proto3. Wykorzystuje się do tego standardowe mapowanie JSON. Wartości prostych typów, takich jak null, int, double i string, są kodowane bezpośrednio i nie uwzględniają ich jednoznacznego 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 formatu JSON, używane jest kodowanie proto3 typu proto3. Więcej informacji znajdziesz w dokumentacji kodowania JSON.

Dozwolone są te typy:

  • null – null
  • int (podpisana lub niepodpisana, do 32-bitowa) – np. 3 lub -30.
  • float, np. 3.14
  • podwójny – np. 3.14
  • wartość logiczna – true lub false
  • string – 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 NaN i Infinity w polach float i double nie są obsługiwane.

Pamiętaj, że long to specjalny typ niedozwolony w formacie JSON, ale podlega specyfikacji 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.

Ponieważ typ nie jest określony dla prostych typów, niektóre wartości po przekroczeniu przewodu zmienią typ. Przekazana wartość float staje się wartością double. Typ short zmienia się w int itd. W Androidzie w przypadku wartości list obsługiwane są zarówno List, jak i JSONArray. W takich przypadkach przekazanie danych w formacie JSONSlate spowoduje wyświetlenie List.

Jeśli mapa z nieznanym polem @type została poddana deserializacji, pozostanie ona mapą. Dzięki temu deweloperzy mogą dodawać do wartości zwracanych pola z nowymi typami pola bez zakłócania pracy starszych klientów.

Przykładowe fragmenty kodu

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

  • Przykład elementu callable.call w języku Swift
  • Odpowiedź na połączenie udana
  • Odpowiedź na niepowodzenie połączenia

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ź na kodowanie

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 z powodzeniem:

{
    "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 z błędem:

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