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

https.onCall триггер для облачных функций является 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, предоставленный клиентским приложением, выполняющим запрос. Бэкэнд автоматически проверяет этот маркер и декодирует его, вводя appId в хендлера context . Если токен не может быть проверен, запрос отклоняется. (Доступно для SDK> = 3.14.0)

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

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

  • application/json не допускается. Он должен быть text/plain или application/x-www-form-urlencoded .
  • Authorization заголовок не CORS-safelisted заголовка запроса .
  • Другие заголовки также не разрешены.

Вызываемая триггер автоматически обрабатывает эти 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 проверку 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]
  • длинный (подписанный или беззнаковый, до 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"
        }
    }
}