Specifiche del protocollo per https.onCall

Un trigger https.onCall per Cloud Functions è un trigger HTTPS con un formato specifico per la richiesta e la risposta. Questa sezione fornisce una specifica per i formati di richiesta e risposta HTTPS utilizzati dagli SDK client per implementare l'API. Queste informazioni potrebbero esserti utili se i tuoi requisiti non possono essere soddisfatti utilizzando gli SDK per Android, Apple o web.

Formato della richiesta: intestazioni

La richiesta HTTP a un endpoint di trigger richiamabile deve essere un POST con le seguenti intestazioni:

  • Obbligatorio: Content-Type: application/json
    • È consentito un ; charset=utf-8 facoltativo.
  • Facoltativo: Authorization: Bearer <token>
  • Facoltativo: Firebase-Instance-ID-Token: <iid>
    • Il token di registrazione FCM dell'SDK client Firebase. Deve essere una stringa. È disponibile nel context del gestore. Viene utilizzato per il targeting delle notifiche push.
  • Facoltativo: X-Firebase-AppCheck: <token>
    • Il token Firebase App Check fornito dall'app client che effettua la richiesta. Il backend verifica automaticamente questo token e lo decodifica, inserendo il appId nel context del gestore. Se non è possibile verificare il token, la richiesta viene rifiutata. (Disponibile per SDK >=3.14.0)

Se vengono incluse altre intestazioni, la richiesta viene rifiutata, come descritto nella documentazione della risposta di seguito.

Nota: nei client JavaScript, queste richieste attivano un preflight CORS OPTIONS, perché:

Il trigger richiamabile gestisce automaticamente queste OPTIONS richieste.

Corpo della richiesta

Il corpo della richiesta HTTP deve essere un oggetto JSON con uno dei seguenti campi:

  • Obbligatorio: data : l'argomento passato alla funzione. Può essere qualsiasi valore JSON valido. Viene decodificato automaticamente nei tipi JavaScript nativi in base al formato di serializzazione descritto di seguito.

Se nella richiesta sono presenti altri campi, il backend considera la richiesta non valida e la rifiuta.

Formato della risposta: codici di stato

Esistono diversi casi che potrebbero comportare codici di stato HTTP e codici di stato stringa diversi per errori nella risposta.

  1. In caso di errore HTTP prima della chiamata del trigger client, la risposta non viene gestita come una funzione client. Ad esempio, se un client tenta di chiamare una funzione inesistente, riceve una risposta 404 Not Found.

  2. Se viene chiamato il trigger client, ma la richiesta è nel formato errato, ad esempio non è JSON, contiene campi non validi o manca il campo data, la richiesta viene rifiutata con 400 Bad Request, con un codice di errore INVALID_ARGUMENT.

  3. Se il token di autenticazione fornito nella richiesta non è valido, la richiesta viene rifiutata con 401 Unauthorized, con un codice di errore UNAUTHENTICATED.

  4. Se il token di registrazione FCM fornito nella richiesta non è valido, il comportamento non è definito. Il token non viene controllato a ogni richiesta, tranne quando viene utilizzato per inviare una notifica push con FCM.

  5. Se viene chiamato il trigger richiamabile, ma non riesce a causa di un'eccezione non gestita o restituisce una promessa non riuscita, la richiesta viene rifiutata con 500 Internal Server Error, con un codice di errore INTERNAL. In questo modo, gli errori di codifica non vengono esposti accidentalmente agli utenti finali.

  6. Se la funzione richiamabile viene chiamata e restituisce una condizione di errore esplicita utilizzando l'API fornita per le funzioni richiamabili, la richiesta non va a buon fine. Il codice di stato HTTP restituito si basa sul mapping ufficiale dello stato di errore allo stato HTTP, come definito in code.proto. Il codice di errore, il messaggio e i dettagli specifici restituiti vengono codificati nel corpo della risposta come descritto di seguito. Ciò significa che se la funzione restituisce un errore esplicito con lo stato OK, la risposta ha lo stato 200 OK, ma il campo error è impostato nella risposta.

  7. Se il trigger client ha esito positivo, lo stato della risposta è 200 OK.

Formato della risposta: intestazioni

La risposta ha le seguenti intestazioni:

  • Content-Type: application/json
  • È consentito un ; charset=utf-8 facoltativo.

Corpo della risposta

La risposta di un endpoint client è sempre un oggetto JSON. Contiene almeno o result o error, insieme a eventuali campi facoltativi. Se la risposta non è un oggetto JSON o non contiene data o error, l'SDK client deve considerare la richiesta non riuscita con il codice di errore Google INTERNAL (13).

  • error : se questo campo è presente, la richiesta viene considerata non riuscita, indipendentemente dal codice di stato HTTP o dalla presenza di data. Il valore di questo campo deve essere un oggetto JSON nel formato di mapping HTTP standard di Google Cloud per gli errori, con campi per status, message e (facoltativamente) details. Il campo code non deve essere incluso. Se il campo status non è impostato o è un valore non valido, il client deve considerare lo stato come INTERNAL, in conformità con code.proto. Se details è presente, viene incluso in tutte le informazioni utente allegate all'errore nell'SDK client, se applicabile.
    Nota: Il campo details qui è un valore fornito dall'utente. Non è necessariamente un elenco di valori con chiave per tipo proto come nel formato Status di Google.
  • result : il valore restituito dalla funzione. Può essere qualsiasi valore JSON valido. L'SDK firebase-functions codifica automaticamente il valore restituito dall'utente in questo formato JSON. Gli SDK client decodificano automaticamente questi parametri nei tipi nativi in base al formato di serializzazione descritto di seguito.

Se sono presenti altri campi, devono essere ignorati.

Serializzazione

Il formato di serializzazione per i payload di dati arbitrari è lo stesso sia per la richiesta sia per la risposta.

Per la coerenza della piattaforma, questi vengono codificati in JSON come se fossero il valore di un campo Any in un buffer di protocollo proto3, utilizzando il mapping JSON standard. I valori di tipi semplici come null, int, double o string vengono codificati direttamente e non includono il tipo esplicito. Pertanto, un float e un double vengono codificati allo stesso modo e potresti non sapere quale viene ricevuto all'altra estremità della chiamata. Per i tipi non nativi di JSON, viene utilizzata la codifica proto3 tipizzata per il valore. Per saperne di più, consulta la documentazione relativa alla codifica JSON di Any.

Sono consentiti i seguenti tipi:

  • null - null
  • int (con o senza segno, fino a 32 bit) - ad es. 3 o -30.
  • float - ad es. 3.14
  • double - ad es. 3.14
  • boolean - true o false
  • string - ad es. "hello world"
  • map<string, any=""> - ad es. {"x": 3}</string,>
  • list - ad es. [1, 2, 3]
  • long (con o senza segno, fino a 64 bit) - [vedi i dettagli di seguito]

I valori NaN e Infinity per float e double non sono supportati.

Tieni presente che long è un tipo speciale non normalmente consentito in JSON, ma è coperto dalla specifica proto3. Ad esempio, questi vengono codificati come:

long

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

unsigned long

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

In generale, la chiave @type deve essere considerata riservata e non utilizzata per le mappe passate.

Poiché il tipo non è specificato per i tipi semplici, alcuni valori cambieranno tipo dopo il passaggio tramite la rete. Un float passato diventa un double. Un short diventa un int e così via. In Android, sia List sia JSONArray sono supportati per i valori di elenco. In questi casi, il passaggio di un JSONArray genererà un List.

Se viene deserializzata una mappa con un campo @type sconosciuto, viene lasciata come mappa. In questo modo, gli sviluppatori possono aggiungere campi con nuovi tipi ai valori restituiti senza interrompere i client precedenti.

Esempi di codice

Gli esempi in questa sezione illustrano come codificare quanto segue:

  • Un esempio di callable.call in Swift
  • Una risposta di successo per la chiamata
  • Una risposta di errore per la chiamata

Esempio di callable.call in Swift da codificare

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

Intestazione della richiesta:

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

Corpo della richiesta:

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

Risposta da codificare

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

Intestazione della risposta di successo:

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

Corpo della risposta di successo:

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

Risposta di errore da codificare

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

Intestazione della risposta di errore:

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

Corpo della risposta di errore:

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