获取我们在 Firebase 峰会上发布的所有信息,了解 Firebase 可如何帮助您加快应用开发速度并满怀信心地运行应用。了解详情

https.onCall 的协议规范

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

Cloud Functions 的https.onCall触发器是具有特定格式的请求和响应的 HTTPS 触发器。本节提供客户端 SDK 用于实现 API 的 HTTPS 请求和响应格式的规范。如果使用 Android、Apple 平台或 Web SDK 无法满足您的要求,此信息可能对您有用。

请求格式:标头

对可调用触发器端点的 HTTP 请求必须是具有以下标头的POST

  • 必需: Content-Type: application/json
    • 一个可选的; charset=utf-8是允许的。
  • 可选: Authorization: Bearer <token>
    • 发出请求的登录用户的 Firebase 身份验证用户 ID 令牌。后端自动验证此令牌并使其在处理程序的context中可用。如果令牌无效,则请求被拒绝。
  • 可选: Firebase-Instance-ID-Token: <iid>
    • Firebase 客户端 SDK 中的 FCM 注册令牌。这必须是一个字符串。这在处理程序的context中可用。它用于定位推送通知。
  • 可选: X-Firebase-AppCheck: <token>
    • 发出请求的客户端应用提供的 Firebase 应用检查令牌。后端自动验证此令牌并对其进行解码,将appId注入处理程序的context 。如果无法验证令牌,则拒绝请求。 (适用于 SDK >=3.14.0)

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

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

可调用触发器自动处理这些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. 如果请求中提供的 FCM 注册令牌无效,则行为未定义。不会在每个请求上检查令牌,除非它用于通过 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 对象。它至少包含resulterror以及任何可选字段。如果响应不是 JSON 对象,或者不包含dataerror ,客户端 SDK 应将请求视为失败,并显示 Google 错误代码INTERNAL (13)

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

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

序列化

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

为了平台的一致性,它们使用 JSON 编码,就好像它们是 proto3 协议缓冲区中Any字段的值一样,使用标准 JSON 映射。简单类型的值,如nullintdoublestring直接编码,不包括它们的显式类型。因此, floatdouble的编码方式相同,您可能不知道在通话的另一端接收到哪个。对于非 JSON 原生的类型,使用值的类型化 proto3 编码。有关更多信息,请参阅任何 JSON 编码的文档

允许以下类型:

  • 空 - null
  • int(有符号或无符号,最多 32 位) - 例如3-30
  • 浮动 - 例如3.14
  • 双倍 - 例如3.14
  • 布尔值 - truefalse
  • 字符串 - 例如"hello world"
  • 地图- 例如{"x": 3}
  • 列表- 例如[1, 2, 3]
  • long (有符号或无符号,最多 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变为double 。一个short变成一个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

成功响应正文:

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