https.onCall 的协议规范

Cloud Functions 的 https.onCall 触发器是一种具有特定请求和响应格式的 HTTPS 触发器。本部分提供了客户端 SDK 用于实现 API 的 HTTPS 请求和响应格式的规范。如果使用 Android SDK、iOS SDK 或网页 SDK 无法满足您的需求,这些信息可能对您会很有用。

请求格式:标头

向 Callable 触发器端点发送的 HTTP 请求必须是带有以下标头的 POST

  • 必需:Content-Type: application/json
    • 允许使用可选的 ; charset=utf-8
  • 可选:Authorization: Bearer <token>
    • 发出请求的已登录用户的 Firebase 身份验证用户 ID 令牌。后端会自动验证此令牌并使其可在处理程序的 context 中找到。如果此令牌无效,则请求会被拒绝。
  • 可选:Firebase-Instance-ID-Token: <iid>
    • 来自 Firebase 客户端 SDK 的实例 ID 令牌。这必须是一个字符串。您可以在处理程序的 context 中找到此令牌。它非常适合用于发送推送通知。

如果请求中还包含任何其他标头,则请求会被拒绝,如下面的响应文档中所述。

注意:在 JavaScript 客户端中,这些请求会触发 CORS OPTIONS 预检,这是因为:

  • application/json 是不允许使用的。只能使用 text/plainapplication/x-www-form-urlencoded
  • Authorization 标头不是属于 CORS 安全列表的请求标头
  • 同样,其他标头也是不允许使用的。

Callable 触发器会自动处理这些 OPTIONS 请求。

请求正文

HTTP 请求的正文应该是具有以下任何字段的 JSON 对象:

  • 必填:data - 传递给函数的参数。这可以是任何有效的 JSON 值。该参数会根据如下所述的序列化格式自动解码为本机 JavaScript 类型。

如果请求中有任何其他字段,则后端会将该请求视为格式错误,并拒绝该请求。

响应格式:状态代码

有几种情况可能会导致响应中错误的 HTTP 状态代码和字符串状态代码有所不同。

  1. 如果在调用 client 触发器之前发生 HTTP 错误,则响应不会作为客户端函数进行处理。例如,如果客户端尝试调用不存在的函数,则它会收到 404 Not Found 响应。

  2. 如果调用了客户端触发器,但请求的格式不正确(例如不是 JSON、包含无效字段或缺少 data 字段),则请求将被拒绝并返回 400 Bad Request,错误代码为 INVALID_ARGUMENT

  3. 如果请求中提供的身份验证令牌无效,则请求将被拒绝并返回 401 Unauthorized,错误代码为 UNAUTHENTICATED

  4. 如果请求中提供的实例 ID 令牌无效,这种行为属于未定义的行为。系统并不会针对每个请求检查实例 ID 令牌,但使用这种令牌通过 FCM 发送推送通知时除外。

  5. 如果调用了 Callable 触发器,但调用失败并产生未处理的异常或返回失败的 Promise,则请求将被拒绝并返回 500 Internal Server Error,错误代码为 INTERNAL。这可以避免编码错误意外地向最终用户显示。

  6. 如果使用为 Callable 函数提供的 API 调用了 Callable 并返回显式错误条件,则请求会失败。系统会根据错误状态与 HTTP 状态的官方映射(如 code.proto 中所定义)返回 HTTP 状态代码。返回的具体错误代码、消息和详细信息会在响应正文中进行编码(如下所述)。这意味着如果函数返回状态为 OK 的显式错误,则响应的状态为 200 OK,但 error 字段会在响应中进行设置。

  7. 如果客户端触发器成功,则响应状态为 200 OK

响应格式:标头

响应具有以下标头:

  • Content-Type: application/json
  • 允许使用可选的 ; charset=utf-8

响应正文

来自客户端端点的响应始终是 JSON 对象。它至少包含 dataerror以及任意可选字段。如果响应不是 JSON 对象,或者不包含 dataerror,则客户端 SDK 应将请求视为失败并返回 Google 错误代码 INTERNAL (13)

  • error - 如果此字段存在,则请求将被视为失败,无论 HTTP 状态代码为何或 data 是否也存在。此字段的值应该是一个 JSON 对象(采用针对错误的标准 Google Cloud HTTP 映射格式),并且包含 statusmessage 和(可选的)details 字段。code 字段不应包含在内。如果 status 字段未设置或是无效值,则客户端应根据 code.proto 将状态视为 INTERNAL。如果存在 details,则其包含在客户端 SDK 中随附于错误的用户信息中(若适用)。
    注意:此处的 details 字段是用户提供的值。它未必是像在 Google Status 格式中那样由原型键控的值列表。
  • data - 函数返回的值。这可以是任何有效的 JSON 值。firebase-functions SDK 会自动将用户返回的值编码为这种 JSON 格式。客户端 SDK 会根据下文所述的序列化格式自动将这些参数解码为本机类型。

如果存在其他字段,则应忽略它们。

序列化

对于请求和响应,任意数据有效负载的序列化格式是相同的。

为保证平台一致性,这些格式根据标准 JSON 映射使用 JSON 编码,就像它们是 proto3 协议缓冲区中 Any 字段的值一样。简单类型(如 nullintdoublestring)的值将直接编码,不会包含它们的显式类型。因此,floatdouble 的编码方式相同,并且您可能不知道在调用的另一端收到了哪一个。对于非 JSON 本机类型,将使用相应值的类型化 proto3 编码。如需了解详情,请参阅任何 JSON 编码的文档

允许使用以下类型:

  • null - null
  • 整数(有符号或无符号,最多 32 位)- 例如 3-30
  • 浮点数 - 例如 3.14
  • 双精度浮点数 - 例如 3.14
  • 布尔值 - truefalse
  • 字符串 - 例如 "hello world"
  • 映射 - 例如 {"x": 3}
  • 列表 - 例如 [1, 2, 3]
  • 长整型(有符号或无符号,最多 64 位)- [详见下文]

不支持 floatdouble 类型的 NaNInfinity 值。

请注意,long 是 JSON 中通常不允许使用的特殊类型,但 proto3 规范涵盖这种类型。例如,这些类型的编码方式如下:

长整型

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

无符号长整型

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

一般情况下,@type 键应该被视为已预留,并且不应该用于传入的映射。

由于没有将相应类型指定为简单类型,因此某些值会在在线传递后改变类型。传入的 float 会成为 doubleshort 会成为 int,依此类推。在 Android 中,ListJSONArray 都是受支持的列表值类型。在这些情况下,传入 JSONArray 将会生成 List

如果包含未知 @type 字段的映射被去序列化,则会被保留为映射。这样,开发者可以将包含新类型的字段添加到返回值中,而不会使较旧的客户端发生服务中断。

代码示例

此部分中的示例说明如何对以下内容编码:

  • Swift 中的 callable.call 示例
  • 调用的成功响应
  • 调用的失败响应

要编码的 Swift 中的 Callable.call 示例

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

成功响应正文:

{
    "data": {
        "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"
        }
    }
}

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面