Триггер 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 Authentication для вошедшего в систему пользователя, отправляющего запрос. Серверная часть автоматически проверяет этот токен и делает его доступным в
- Необязательно:
Firebase-Instance-ID-Token: <iid>
- Токен регистрации FCM из клиентского SDK Firebase. Это должна быть строка. Это доступно в
context
обработчика. Он используется для таргетинга push-уведомлений.
- Токен регистрации FCM из клиентского SDK Firebase. Это должна быть строка. Это доступно в
- Необязательно:
X-Firebase-AppCheck: <token>
- Токен Firebase App Check, предоставленный клиентским приложением, выполняющим запрос. Бэкенд автоматически проверяет этот токен и декодирует его, внедряя
appId
вcontext
обработчика. Если токен не может быть проверен, запрос отклоняется. (Доступно для SDK >=3.14.0)
- Токен Firebase App Check, предоставленный клиентским приложением, выполняющим запрос. Бэкенд автоматически проверяет этот токен и декодирует его, внедряя
Если включены какие-либо другие заголовки, запрос отклоняется, как описано в документации по ответу ниже.
Примечание. В клиентах JavaScript эти запросы запускают предварительную проверку CORS OPTIONS
, потому что:
-
application/json
не разрешено. Он должен бытьtext/plain
илиapplication/x-www-form-urlencoded
. - Заголовок
Authorization
не является заголовком запроса, внесенным в список надежных отправителей CORS . - Другие заголовки также не допускаются.
Вызываемый триггер автоматически обрабатывает эти запросы OPTIONS
.
Тело запроса
Тело HTTP-запроса должно быть объектом JSON с любым из следующих полей:
- Требуется:
data
— аргумент, передаваемый функции. Это может быть любое допустимое значение JSON. Это автоматически декодируется в собственные типы JavaScript в соответствии с форматом сериализации, описанным ниже.
Если в запросе присутствуют какие-либо другие поля, серверная часть считает запрос искаженным и отклоняет его.
Формат ответа: коды состояния
Есть несколько случаев, которые могут привести к различным кодам состояния HTTP и строковым кодам состояния для ошибок в ответе.
В случае ошибки HTTP до вызова
client
триггера ответ не обрабатывается как клиентская функция. Например, если клиент пытается вызвать несуществующую функцию, он получает ответ404 Not Found
.Если клиентский триггер вызывается, но запрос имеет неправильный формат, например не является JSON, содержит недопустимые поля или отсутствует поле
data
, запрос отклоняется с кодом ошибки400 Bad Request
с кодом ошибкиINVALID_ARGUMENT
.Если токен аутентификации, указанный в запросе, недействителен, запрос отклоняется с кодом ошибки
401 Unauthorized
с кодом ошибкиUNAUTHENTICATED
.Если маркер регистрации FCM, предоставленный в запросе, недействителен, поведение не определено. Токен не проверяется при каждом запросе, за исключением случаев, когда он используется для отправки push-уведомления с помощью FCM.
Если вызываемый триггер вызывается, но завершается сбоем с необработанным исключением или возвращает невыполненное обещание, запрос отклоняется с кодом
500 Internal Server Error
с кодом ошибкиINTERNAL
. Это предотвращает случайное раскрытие ошибок кодирования конечным пользователям.Если вызываемый объект вызывается и возвращает явное условие ошибки с использованием API, предоставленного для вызываемых функций, то запрос завершается неудачно. Возвращаемый код состояния HTTP основан на официальном сопоставлении статуса ошибки со статусом HTTP, как определено в code.proto . Конкретный код ошибки, сообщение и возвращаемые сведения кодируются в тексте ответа, как описано ниже. Это означает, что если функция возвращает явную ошибку со статусом
OK
, то ответ имеет статус200 OK
, но в ответе установлено полеerror
.Если клиентский триггер выполнен успешно, статус ответа —
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
здесь задается пользователем. Это не обязательно список значений с ключами по типу прототипа, как в формате GoogleStatus
. -
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"
}
}
}