Especificação do protocolo para https.onCall

Um acionador https.onCall para o Cloud Functions é um acionador HTTPS com um formato específico para a solicitação e a resposta. Veja aqui uma especificação dos formatos de solicitação e resposta HTTPS usados pelos SDKs do cliente para implementar a API. Essas informações podem ser úteis se os requisitos não puderem ser atendidos usando os SDKs do Android, do iOS ou da Web.

Formato de solicitação: cabeçalhos

A solicitação HTTP para um ponto de extremidade de acionamento chamável precisa ser um POST com os seguintes cabeçalhos:

  • Obrigatório: Content-Type: application/json
    • Um ; charset=utf-8 opcional é permitido.
  • Opcional: Authorization: Bearer <token>
    • Um token de código do usuário do Firebase Authentication para o usuário conectado que fez a solicitação. O back-end verifica automaticamente esse token e o disponibiliza no context do manipulador. Se o token não for válido, a solicitação será rejeitada.
  • Opcional: Firebase-Instance-ID-Token: <iid>
    • O token de código da instância do SDK do cliente do Firebase. Precisa ser uma string. Está disponível no context do manipulador. É particularmente útil para enviar notificações push.

Se outros cabeçalhos forem incluídos, a solicitação será rejeitada, conforme descrito na documentação de resposta abaixo.

Observação: em clientes JavaScript, essas solicitações acionam uma pré-visualização do CORS OPTIONS pelos seguintes motivos:

O acionador selecionável manipula automaticamente essas solicitações OPTIONS.

Corpo da solicitação

O corpo da solicitação HTTP deve ser um objeto JSON com qualquer um dos seguintes campos:

  • Obrigatório: data - o argumento passado para a função. Pode ser qualquer valor JSON válido. É automaticamente decodificado em tipos JavaScript nativos de acordo com o formato de serialização descrito abaixo.

Se houver outros campos presentes na solicitação, o back-end considerará a solicitação malformada e ela será rejeitada.

Formato de resposta: códigos de status

Há vários casos que podem resultar em códigos de status de HTTP e de string diferentes para erros na resposta.

  1. No caso de um erro HTTP antes de o acionador do client ser chamado, a resposta não é tratada como uma função do cliente. Por exemplo, se um cliente tentar invocar uma função inexistente, ele receberá uma resposta 404 Not Found.

  2. Se o acionador do cliente for chamado, mas a solicitação estiver no formato incorreto, como não ser JSON, com campos inválidos ou sem o campo de data, a solicitação será rejeitada com 400 Bad Request, com um código de erro INVALID_ARGUMENT.

  3. Se o token de autorização fornecido na solicitação for inválido, a solicitação será rejeitada com 401 Unauthorized, com um código de erro UNAUTHENTICATED.

  4. Se o token do código da instância fornecido na solicitação for inválido, o comportamento é indefinido. O token do código da instância não está marcado em todas as solicitações, exceto quando é usado para enviar uma notificação por push com o FCM.

  5. Se o acionador chamável for invocado, mas falhar com uma exceção não manipulada ou retornar uma promessa com falha, a solicitação será rejeitada com 500 Internal Server Error, com um código de erro de INTERNAL. Isso evita que erros de codificação sejam acidentalmente expostos a usuários finais.

  6. Se o acionador chamável for invocado e retornar uma condição de erro explícita usando a API fornecida para funções chamáveis, a solicitação falhará. O código de status HTTP retornado é baseado no mapeamento oficial do status de erro para o status HTTP, conforme definido no code.proto. O código de erro específico, a mensagem e os detalhes retornados são codificados no corpo da resposta, conforme detalhado abaixo. Isso significa que, se a função retornar um erro explícito com status OK, a resposta terá status 200 OK, mas o campo error será definido na resposta.

  7. Se o acionador do cliente for bem-sucedido, o status da resposta será 200 OK.

Formato de resposta: cabeçalhos

A resposta tem os seguintes cabeçalhos:

  • Content-Type: application/json
  • Um ; charset=utf-8 opcional é permitido.

Corpo da resposta

A resposta de um ponto de extremidade do cliente é sempre um objeto JSON. No mínimo, contém data ou error, juntamente com quaisquer campos opcionais. Se a resposta não for um objeto JSON, ou não contiver data ou error, o SDK do cliente deverá considerar que a solicitação falhou com o código de erro do Google INTERNAL (13).

  • error: se este campo estiver presente, a solicitação será considerada com falha, independentemente do código de status HTTP ou se data também está presente. O valor desse campo deve ser um objeto JSON no formato padrão do mapeamento HTTP do Google Cloud para erros, com campos para status, message e, opcionalmente, details. O campo code não deve ser incluído. Se o campo de status não estiver definido ou for um valor inválido, o cliente deverá tratar o status como INTERNAL, de acordo com o code.proto. Se houver details, ele será incluído em qualquer informação de usuário anexada ao erro no SDK do cliente, se aplicável.
    Observação: o campo details aqui é um valor fornecido pelo usuário. Não é necessariamente uma lista de valores codificados por protótipos como no formato Status do Google.
  • data: o valor retornado pela função. Pode ser qualquer valor JSON válido. O SDK firebase-functions codifica automaticamente o valor retornado pelo usuário para esse formato JSON. Os SDKs do cliente decodificam automaticamente esses parâmetros em tipos nativos de acordo com o formato de serialização descrito abaixo.

Se outros campos estiverem presentes, eles devem ser ignorados.

Serialização

O formato de serialização para payloads arbitrários é o mesmo para a solicitação e a resposta.

Para consistência com a plataforma, eles são codificados em JSON como se fossem o valor de um campo Any em um buffer de protocolo proto3, usando o mapeamento JSON padrão. Os valores de tipos simples, como null, int, double ou string são codificados diretamente e não incluem o tipo explícito deles. Assim, um float e double são codificados da mesma maneira, e você pode não saber qual é recebido no outro lado da chamada. Para tipos que não são nativos para JSON, a codificação proto3 digitada para o valor é usada. Para mais informações, consulte a documentação "Qualquer codificação JSON".

Os seguintes tipos são permitidos:

  • null: null
  • int (assinado ou não, até 32 bits): por exemplo, 3 ou -30
  • float: por exemplo, 3.14
  • double: por exemplo, 3.14
  • boolean: true ou false
  • string: por exemplo, "hello world"
  • map: por exemplo, {"x": 3}
  • list: por exemplo, [1, 2, 3]
  • long (assinado ou não, até 64 bits): mais detalhes abaixo

Valores NaN e Infinity por float e double não são compatíveis.

Observe que long é um tipo especial que normalmente não é permitido em JSON, mas é coberto pela especificação proto3. Por exemplo, estes são codificados como:

long

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

long não assinado

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

Em geral, a chave @type deve ser considerada reservada e não usada para mapas passados.

Como o tipo não é especificado para tipos simples, alguns valores mudam de tipo após passarem pelo fio. Um float passado se torna um double. Um short se torna um int e assim por diante. No Android, List e JSONArray são compatíveis para valores de lista. Nesses casos, a transmissão em um JSONArray gerará uma List.

Se um mapa com um campo desconhecido @type for desserializado, ele será deixado como um mapa. Assim, os desenvolvedores podem adicionar campos com novos tipos aos valores de retorno sem prejudicar clientes mais antigos.

Amostras de código

As amostras nesta seção ilustram como codificar o seguinte:

  • Um exemplo de callable.call no Swift
  • Uma resposta de êxito para a chamada
  • Uma resposta de falha para a chamada

Exemplo de Callable.call no Swift para codificação

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

Cabeçalho da solicitação:

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

Corpo da solicitação:

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

Resposta para codificação

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

Cabeçalho de resposta bem-sucedida:

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

Corpo de resposta bem-sucedida:

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

Resposta com falha para codificação

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

Cabeçalho da resposta com falha:

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

Corpo de resposta com falha:

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

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.