Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Спецификация протокола для https.onCall

Оптимизируйте свои подборки Сохраняйте и классифицируйте контент в соответствии со своими настройками.

Триггер https.onCall для Cloud Functions — это триггер HTTPS с определенным форматом запроса и ответа. В этом разделе представлена ​​спецификация форматов запросов и ответов HTTPS, используемых клиентскими пакетами SDK для реализации API. Эта информация может быть вам полезна, если ваши требования не могут быть выполнены с помощью платформ Android, Apple или веб-SDK.

Формат запроса: заголовки

HTTP-запрос к вызываемой конечной точке триггера должен быть POST со следующими заголовками:

  • Требуется: Content-Type: application/json
    • Необязательный ; charset=utf-8 разрешено.
  • Необязательно: Authorization: Bearer <token>
    • Токен идентификатора пользователя Firebase Authentication для вошедшего в систему пользователя, отправляющего запрос. Серверная часть автоматически проверяет этот токен и делает его доступным в context обработчика. Если токен недействителен, запрос отклоняется.
  • Необязательно: Firebase-Instance-ID-Token: <iid>
    • Токен регистрации FCM из клиентского SDK Firebase. Это должна быть строка. Это доступно в context обработчика. Он используется для таргетинга push-уведомлений.
  • Необязательно: X-Firebase-AppCheck: <token>
    • Токен Firebase App Check, предоставленный клиентским приложением, выполняющим запрос. Бэкенд автоматически проверяет этот токен и декодирует его, appId в context обработчика. Если токен не может быть проверен, запрос отклоняется. (Доступно для SDK >=3.14.0)

Если включены какие-либо другие заголовки, запрос отклоняется, как описано в документации по ответу ниже.

Примечание. В клиентах JavaScript эти запросы запускают предварительную проверку CORS OPTIONS , потому что:

Вызываемый триггер автоматически обрабатывает эти запросы OPTIONS .

Тело запроса

Тело HTTP-запроса должно быть объектом JSON с любым из следующих полей:

  • Требуется: data — аргумент, передаваемый функции. Это может быть любое допустимое значение JSON. Это автоматически декодируется в собственные типы JavaScript в соответствии с форматом сериализации, описанным ниже.

Если в запросе присутствуют какие-либо другие поля, серверная часть считает запрос искаженным и отклоняет его.

Формат ответа: коды состояния

Есть несколько случаев, которые могут привести к различным кодам состояния HTTP и строковым кодам состояния для ошибок в ответе.

  1. В случае ошибки HTTP до вызова client триггера ответ не обрабатывается как клиентская функция. Например, если клиент пытается вызвать несуществующую функцию, он получает ответ 404 Not Found .

  2. Если клиентский триггер вызывается, но запрос имеет неправильный формат, например не является JSON, содержит недопустимые поля или отсутствует поле data , запрос отклоняется с кодом ошибки 400 Bad Request с кодом ошибки INVALID_ARGUMENT .

  3. Если токен аутентификации, указанный в запросе, недействителен, запрос отклоняется с кодом ошибки 401 Unauthorized с кодом ошибки UNAUTHENTICATED .

  4. Если маркер регистрации FCM, предоставленный в запросе, недействителен, поведение не определено. Токен не проверяется при каждом запросе, за исключением случаев, когда он используется для отправки push-уведомления с помощью FCM.

  5. Если вызываемый триггер вызывается, но завершается сбоем с необработанным исключением или возвращает невыполненное обещание, запрос отклоняется с кодом 500 Internal Server Error с кодом ошибки INTERNAL . Это предотвращает случайное раскрытие ошибок кодирования конечным пользователям.

  6. Если вызываемый объект вызывается и возвращает явное условие ошибки с использованием API, предоставленного для вызываемых функций, то запрос завершается неудачно. Возвращаемый код состояния HTTP основан на официальном сопоставлении статуса ошибки со статусом HTTP, как определено в code.proto . Конкретный код ошибки, сообщение и возвращаемые сведения кодируются в тексте ответа, как описано ниже. Это означает, что если функция возвращает явную ошибку со статусом OK , то ответ имеет статус 200 OK , но в ответе установлено поле error .

  7. Если клиентский триггер выполнен успешно, статус ответа — 200 OK .

Формат ответа: заголовки

Ответ имеет следующие заголовки:

  • Content-Type: application/json
  • Необязательный ; charset=utf-8 разрешено.

Тело ответа

Ответ от конечной точки клиента всегда представляет собой объект JSON. Как минимум, он содержит либо result , либо error , а также любые необязательные поля. Если ответ не является объектом JSON или не содержит data или error , клиентский SDK должен рассматривать запрос как неудавшийся с кодом ошибки Google INTERNAL (13) .

  • error — если это поле присутствует, то запрос считается неудачным, независимо от кода состояния HTTP или наличия data . Значение этого поля должно быть объектом JSON в стандартном формате Google Cloud HTTP Mapping для ошибок, с полями для status , message и (необязательно) details . Поле code не должно быть включено. Если поле status не задано или имеет недопустимое значение, клиент должен рассматривать состояние как INTERNAL в соответствии с code.proto . Если details присутствуют, они включаются в любую информацию о пользователе, прикрепленную к ошибке в клиентском SDK, если это применимо.
    Примечание. Поле details здесь задается пользователем. Это не обязательно список значений с ключами по типу прототипа, как в формате Google Status .
  • result - значение, возвращаемое функцией. Это может быть любое допустимое значение JSON. SDK firebase-functions автоматически кодирует значение, возвращаемое пользователем, в этот формат JSON. Клиентские SDK автоматически декодируют эти параметры в собственные типы в соответствии с форматом сериализации, описанным ниже.

Если присутствуют другие поля, их следует игнорировать.

Сериализация

Формат сериализации для произвольных полезных данных одинаков как для запроса, так и для ответа.

Для согласованности с платформой они кодируются в JSON, как если бы они были значением поля Any в буфере протокола proto3, с использованием стандартного сопоставления JSON . Значения простых типов, таких как null , int , double или string , кодируются напрямую и не включают их явный тип. Таким образом, float и double кодируются одинаково, и вы можете не знать, что получено на другом конце вызова. Для типов, не являющихся родными для JSON, используется типизированная кодировка proto3 для значения. Дополнительные сведения см. в документации по любой кодировке JSON .

Допускаются следующие типы:

  • ноль - null
  • int (со знаком или без знака, до 32 бит) - например, 3 или -30 .
  • поплавок - например 3.14
  • двойной - например 3.14
  • логическое значение - true или false
  • строка - например "hello world"
  • карта - например, {"x": 3}
  • список - например [1, 2, 3]
  • long (со знаком или без знака, до 64 бит) - [подробности см. ниже]

Значения NaN и Infinity для float и double не поддерживаются.

Обратите внимание, что long — это специальный тип, обычно не разрешенный в JSON, но на него распространяется спецификация proto3. Например, они кодируются как:

длинная

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

беззнаковый длинный

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

В общем, ключ @type следует считать зарезервированным и не использовать для передаваемых карт.

Поскольку для простых типов тип не указан, некоторые значения изменят тип после передачи по сети. float , переданный внутрь, становится double . short становится int и так далее. В Android для значений списка поддерживаются как List , так и JSONArray . В этих случаях передача JSONArray даст List .

Если карта с неизвестным полем @type десериализована, она остается картой. Это позволяет разработчикам добавлять поля с новыми типами к своим возвращаемым значениям, не нарушая работу старых клиентов.

Примеры кода

Примеры в этом разделе иллюстрируют, как кодировать следующее:

  • Пример callable.call в Swift
  • Успешный ответ на вызов
  • Неудачный ответ на вызов

Пример Callable.call в Swift для кодирования

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

Заголовок запроса:

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

Тело запроса:

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

Ответ на кодирование

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

Заголовок успешного ответа:

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

Успешный ответ:

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

Ошибка ответа на кодирование

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

Неудачный заголовок ответа:

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

Неудачный ответ:

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