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