Specyfikacja protokołu dla https.onCall

Aktywator https.onCall w Cloud Functions to aktywator 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 implementowania interfejsu API. Te informacje mogą być przydatne, jeśli Twoje wymagania nie mogą zostać spełnione przy użyciu pakietów SDK na Androida, platformę Apple lub do internetu.

Format żądania: nagłówki

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

  • Wymagane: Content-Type: application/json
    • Opcjonalnie można dodać ; charset=utf-8.
  • Opcjonalnie: Authorization: Bearer <token>
    • Token identyfikatora użytkownika dla zalogowanego użytkownika, który wysyła żądanie.Firebase Authentication 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 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 dostarczony przez aplikację kliencką, która wysyła żądanie. Backend automatycznie weryfikuje ten token i dekoduje go, wstawiając appId do context modułu obsługi. Jeśli nie można zweryfikować tokena, żądanie zostaje odrzucone. (Dostępne w pakiecie SDK w wersji >= 3.14.0)

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

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

  • application/json jest niedozwolone. Musi to być text/plain lub application/x-www-form-urlencoded.
  • Nagłówek Authorization nie jest nagłówkiem żądania bezpiecznym dla CORS.
  • Inne nagłówki są podobnie niedozwolone.

Aktywator wywoływany automatycznie obsługuje te żądania OPTIONS.

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 ona automatycznie dekodowana na natywne typy JavaScript 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ć zwracanie różnych kodów stanu HTTP i ciągów znaków stanu dla błędów w odpowiedzi.

  1. W przypadku błędu HTTP przed wywołaniem aktywatora 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 aktywator klienta zostanie wywołany, ale żądanie będzie miało nieprawidłowy format, np. nie będzie w formacie JSON, będzie zawierać nieprawidłowe pola lub będzie brakować pola data, żądanie zostanie odrzucone z kodem 400 Bad Request i kodem błędu INVALID_ARGUMENT.

  3. Jeśli token uwierzytelniania 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, zachowanie 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 aktywator wywoływany 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 wywołanie zostanie wywołane i zwróci wyraźny stan błędu za pomocą interfejsu API udostępnionego dla funkcji wywoływanych, żądanie zakoń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ą kodowane w treści odpowiedzi, jak opisano poniżej. Oznacza to, że jeśli funkcja zwróci wyraźny błąd ze stanem OK, odpowiedź będzie miała stan 200 OK, ale w odpowiedzi zostanie ustawione pole error.

  7. Jeśli aktywator klienta działa prawidłowo, stan odpowiedzi to 200 OK.

Format odpowiedzi: nagłówki

Odpowiedź ma te nagłówki:

  • Content-Type: application/json
  • Opcjonalnie można dodać ; 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 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 data jest też obecne. Wartość tego pola powinna być obiektem JSON w standardowym formacie mapowania błędów HTTP w Google Cloud z polami status, message i (opcjonalnie) details. Pole code nie powinno być uwzględniane. Jeśli pole status jest nieustawione lub ma nieprawidłową wartość, klient powinien traktować stan jako INTERNAL zgodnie z code.proto. Jeśli pole details jest obecne, jest ono uwzględniane w informacjach o użytkowniku dołączonych do błędu w pakiecie SDK klienta, jeśli ma to zastosowanie.
    Uwaga: pole details zawiera wartość podaną przez użytkownika. Nie musi to być lista wartości z kluczami według typu proto, jak w formacie Status Google.
  • result – wartość zwrócona 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. Pakiety SDK klienta automatycznie dekodują te parametry na typy natywne zgodnie z formatem serializacji opisanym poniżej.

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

Serializacja

Format serializacji dowolnych ładunków danych jest taki sam w przypadku żądania 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ą swojego jawnego typu. Dlatego float i double są kodowane w ten sam sposób i nie można stwierdzić, który z nich jest odbierany po drugiej stronie wywołania. W przypadku typów, które nie są natywne dla formatu JSON, używane jest kodowanie proto3 z typami dla wartości. Więcej informacji znajdziesz w dokumentacji kodowania JSON Any.

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
  • boolean – true lub false
  • string – np. "hello world"
  • map<string, any=""> – np. {"x": 3}</string,>
  • list – np. [1, 2, 3]
  • long (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.

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 kodowane w ten sposób:

long

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

unsigned long

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

Ogólnie rzecz biorąc, klucz @type należy traktować jako zarezerwowany i nie używać go w przypadku przekazywanych map.

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

Jeśli mapa z nieznanym polem @type zostanie zdeserializowana, pozostanie mapą. Umożliwia to deweloperom dodawanie do zwracanych wartości pól z nowymi typami bez przerywania działania starszych klientów.

Przykładowe fragmenty kodu

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

  • Przykład callable.call w języku Swift
  • Odpowiedź na wywołanie w przypadku powodzenia
  • Odpowiedź na wywołanie w przypadku niepowodzenia

Przykład 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 w przypadku powodzenia:

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

Treść odpowiedzi w przypadku powodzenia:

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

Odpowiedź w przypadku niepowodzenia do zakodowania

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

Nagłówek odpowiedzi w przypadku niepowodzenia:

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

Treść odpowiedzi w przypadku niepowodzenia:

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