Catch up on highlights from Firebase at Google I/O 2023. Learn more

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 App Check 令牌。後端自動驗證此令牌並對其進行解碼,將appId注入處理程序的context中。如果無法驗證令牌,則拒絕請求。 (適用於 SDK >=3.14.0)

如果包含任何其他標頭,請求將被拒絕,如下面的響應文檔中所述。

注意:在 JavaScript 客戶端中,這些請求會觸發 CORS OPTIONS預檢,因為:

  • application/json是不允許的。它必須是text/plainapplication/x-www-form-urlencoded
  • Authorization標頭不是CORS 安全列表請求標頭
  • 同樣不允許使用其他標頭。

可調用觸發器自動處理這些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 映射以 JSON 編碼,就好像它們是 proto3 協議緩衝區中Any字段的值一樣。 nullintdoublestring等簡單類型的值直接編碼,不包括它們的顯式類型。因此, floatdouble的編碼方式相同,您可能不知道呼叫的另一端收到了哪個。對於非 JSON 原生的類型,使用值的類型化 proto3 編碼。有關詳細信息,請參閱任何 JSON 編碼的文檔

允許以下類型:

  • 空 - null
  • int(有符號或無符號,最多 32 位)- 例如3-30
  • 浮動 - 例如3.14
  • 雙 - 例如3.14
  • 布爾值 - truefalse
  • 字符串 - 例如"hello world"
  • 地圖- 例如{"x": 3}
  • 列表- 例如[1, 2, 3]
  • long(有符號或無符號,最多 64 位)- [詳情見下文]

不支持floatdoubleNaNInfinity值。

請注意, 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"
        }
    }
}