Specyfikacja protokołu dla https.onCall

https.onCall Wyzwalacz Cloud Functions to wyzwalacz HTTPS o określonym formacie żądania i odpowiedzi. W tej sekcji znajdziesz specyfikację formatów żądań i odpowiedzi HTTPS używanych przez pakiety SDK klienta do implementacji interfejsu API. Te informacje mogą być przydatne, jeśli Twoje wymagania nie mogą zostać spełnione przy użyciu pakietów SDK na platformy Android, Apple lub w internecie.

Format żądania: nagłówki

Żądanie HTTP do punktu końcowego wywoływanego wyzwalacza musi być żądaniem POST z tymi nagłówkami:

  • Wymagane: Content-Type: application/json
    • Dozwolony jest opcjonalny znak ; charset=utf-8.
  • Opcjonalnie: Authorization: Bearer <token>
    • Firebase Authentication token identyfikatora użytkownika zalogowanego, 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 zostanie odrzucone.
  • Opcjonalnie: Firebase-Instance-ID-Token: <iid>
    • Token rejestracji FCM z pakietu SDK klienta Firebase. Musi to być ciąg znaków. Jest on dostępny w context modułu obsługi. Służy do kierowania powiadomień push.
  • Opcjonalnie: X-Firebase-AppCheck: <token>
    • Token Sprawdzania aplikacji Firebase udostępniony przez aplikację kliencką wysyłającą żądanie. Backend automatycznie weryfikuje ten token i go dekoduje, wstawiając appId do context modułu obsługi. Jeśli nie można zweryfikować tokena, żądanie zostanie odrzucone. (Dostępne w przypadku pakietu SDK w wersji 3.14.0 lub nowszej)

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

Uwaga: w przypadku klientów JavaScript te żądania wywołują wstępne żądanie CORS OPTIONS, ponieważ:

  • application/json – to jest niedozwolone. Musi to być text/plain lub application/x-www-form-urlencoded.
  • Nagłówek Authorization nie jest nagłówkiem żądania CORS-safelisted.
  • Podobnie nie są dozwolone inne nagłówki.

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

Treść żądania

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

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

Jeśli w żądaniu znajdują się inne pola, backend uzna je za nieprawidłowe i odrzuci żądanie.

Format odpowiedzi: kody stanu

Istnieje kilka przypadków, które mogą powodować różne kody stanu HTTP i kody stanu w postaci ciągów znaków w przypadku błędów w odpowiedzi.

  1. W przypadku błędu HTTP przed wywołaniem wyzwalacza client odpowiedź nie jest traktowana 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ływany jest wyzwalacz klienta, ale żądanie ma nieprawidłowy format (np. nie jest w formacie JSON, zawiera nieprawidłowe pola lub brakuje w nim pola data), żądanie jest odrzucane z kodem 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 401 Unauthorized i kodem błędu UNAUTHENTICATED.

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

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

  6. Jeśli funkcja wywoływana jest wywoływana i zwraca jawny stan błędu za pomocą interfejsu API udostępnionego dla funkcji wywoływanych, żądanie kończy się niepowodzeniem. Zwracany kod stanu HTTP jest oparty na oficjalnym mapowaniu stanu błędu na stan HTTP, zgodnie z definicją w code.proto. Konkretny kod błędu, komunikat i szczegóły są zwracane w treści odpowiedzi w sposób opisany 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 zostanie ustawione pole error.

  7. Jeśli wywołanie klienta się powiedzie, stan odpowiedzi to 200 OK.

Format odpowiedzi: nagłówki

Odpowiedź zawiera te nagłówki:

  • Content-Type: application/json
  • Dozwolony jest opcjonalny znak ; charset=utf-8.

Treść odpowiedzi

Odpowiedź z punktu końcowego klienta jest zawsze obiektem JSON. Zawiera co najmniej result lub error oraz wszystkie pola opcjonalne. Jeśli odpowiedź nie jest obiektem JSON lub nie zawiera wartości data ani error, pakiet SDK klienta powinien traktować żądanie jako nieudane i zwrócić kod 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 pole data jest również obecne. Wartość tego pola powinna być obiektem JSON w standardowym formacie mapowania HTTP Google Cloud dla błędów, z polami status, message i (opcjonalnie) details. Pola code nie należy uwzględniać. Jeśli pole status nie jest ustawione lub ma nieprawidłową wartość, klient powinien traktować stan jako INTERNAL zgodnie z plikiem code.proto. Jeśli występuje symbol details, jest on uwzględniany w informacjach o użytkowniku dołączanych do błędu w pakiecie SDK klienta (w stosownych przypadkach).
    Uwaga: pole details zawiera wartość podaną przez użytkownika. Nie musi to być lista wartości kluczowanych według typu proto, jak w formacie Google Status.
  • result – wartość zwracana przez funkcję. Może to być dowolna prawidłowa wartość JSON. Pakiet SDK firebase-functions automatycznie koduje wartość zwróconą przez użytkownika w tym formacie JSON. Klienckie pakiety SDK automatycznie dekodują te parametry do typów natywnych zgodnie z formatem serializacji opisanym poniżej.

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 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 zawierają jawnego typu. Dlatego znaki floatdouble są kodowane w ten sam sposób i możesz nie wiedzieć, który z nich zostanie odebrany na drugim końcu połączenia. W przypadku typów, które nie są natywne dla JSON, używane jest kodowanie proto3 z określonym typem wartości. Więcej informacji znajdziesz w dokumentacji kodowania Any JSON.

Dozwolone są te typy:

  • null - null
  • int (ze znakiem lub bez znaku, do 32 bitów) – np. 3 lub -30.
  • float – np. 3.14
  • double – np. 3.14
  • wartość logiczna – true lub false
  • ciąg znaków – np. "hello world"
  • map<string, any=""> - e.g. {"x": 3}</string,>
  • list – np. [1, 2, 3]
  • long (ze znakiem lub bez znaku, do 64 bitów) – [szczegółowe informacje znajdziesz poniżej];

Wartości NaNInfinity w przypadku pól floatdouble nie są obsługiwane.

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

Liczba długa

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

unsigned long

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

Ogólnie klucz @type należy uznać za zarezerwowany i nie używać go w przypadku przekazywanych map.

Ponieważ typ nie jest określony w przypadku typów prostych, niektóre wartości zmienią typ po przesłaniu przez sieć. float staje się double. short staje się int itd. Na Androidzie w przypadku wartości listy obsługiwane są zarówno List, jak i JSONArray. W takich przypadkach przekazanie obiektu JSONArray spowoduje zwrócenie wartości List.

Jeśli mapa z nieznanym polem @type zostanie zdeserializowana, pozostanie mapą. Dzięki temu deweloperzy mogą dodawać do zwracanych wartości pola z nowymi typami bez powodowania problemów u starszych klientów.

Przykładowe fragmenty kodu

Przykłady w tej sekcji pokazują, jak zakodować te elementy:

  • Przykład callable.call w Swift
  • Odpowiedź o sukcesie wywołania
  • Odpowiedź o błędzie w przypadku 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ź do zakodowania

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

Nagłówek odpowiedzi w sytuacji powodzenia:

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

Treść odpowiedzi w przypadku powodzenia:

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

Nie udało się zakodować odpowiedzi

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

Nagłówek odpowiedzi o błędzie:

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

Treść odpowiedzi w przypadku błędu:

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