Cloud Functions 的 https.onCall
觸發條件是 HTTPS 觸發條件,要求和回應的格式皆為特定格式。本節提供用戶端 SDK 用於實作 API 的 HTTPS 要求和回應格式規格。如果 Android、Apple 平台或網頁 SDK 無法滿足您的需求,這項資訊可能非常實用。
要求格式:標頭
傳送至可呼叫的觸發事件端點的 HTTP 要求必須是 POST
,且包含下列標頭:
- 必要項目:
Content-Type: application/json
- 允許選用的
; charset=utf-8
。
- 允許選用的
- 選用:
Authorization: Bearer <token>
- 針對提出要求的登入使用者,提供 Firebase Authentication 使用者 ID 權杖。後端會自動驗證這個符記,並在處理常式
context
中提供該符記。如果權杖無效,要求就會遭到拒絕。
- 針對提出要求的登入使用者,提供 Firebase Authentication 使用者 ID 權杖。後端會自動驗證這個符記,並在處理常式
- 選用:
Firebase-Instance-ID-Token: <iid>
- Firebase 用戶端 SDK 中的 FCM 註冊權杖。必須為字串。這項資訊可在處理程序的
context
中取得。用於指定推播通知。
- Firebase 用戶端 SDK 中的 FCM 註冊權杖。必須為字串。這項資訊可在處理程序的
- 選用:
X-Firebase-AppCheck: <token>
- 發出要求的用戶端提供的 Firebase App Check 權杖。後端會自動驗證這個權杖並將其解碼,將
appId
插入處理常式的context
中。如果無法驗證權杖,要求就會遭到拒絕。(適用於 SDK 3.14.0 以上版本)。
- 發出要求的用戶端提供的 Firebase App Check 權杖。後端會自動驗證這個權杖並將其解碼,將
如果包含任何其他標頭,系統會拒絕要求,如以下回應文件所述。
注意:在 JavaScript 用戶端中,這些要求會觸發 CORS OPTIONS
預先飛航,原因如下:
- 不允許
application/json
。必須是text/plain
或application/x-www-form-urlencoded
。 Authorization
標頭並非 CORS 安全清單要求標頭。- 同樣地,系統也不允許其他標頭。
可呼叫的觸發事件會自動處理這些 OPTIONS
要求。
要求主體
HTTP 要求的主體應為 JSON 物件,其中包含下列任一欄位:
- 必填:
data
- 傳遞至函式的引數。這可以是任何有效的 JSON 值。系統會根據下列說明的序列化格式,自動將其解碼為原生 JavaScript 類型。
如果要求中包含任何其他欄位,後端會將要求視為格式錯誤,並予以拒絕。
回應格式:狀態碼
有幾種情況可能會導致回應中出現不同的 HTTP 狀態碼和字串狀態碼,代表錯誤。
如果在叫用
client
觸發事件之前發生 HTTP 錯誤,系統不會將回應視為用戶端函式處理。舉例來說,如果用戶端嘗試叫用不存在的函式,就會收到404 Not Found
回應。如果叫用用戶端觸發事件,但要求格式不正確 (例如不是 JSON、包含無效欄位,或缺少
data
欄位),系統會以400 Bad Request
拒絕要求,並傳回錯誤代碼INVALID_ARGUMENT
。如果要求中提供的授權權杖無效,系統會拒絕要求,並傳回
401 Unauthorized
和UNAUTHENTICATED
錯誤代碼。如果要求中提供的 FCM 註冊權杖無效,系統就不會定義該行為。權杖只會在透過 FCM 傳送推播通知時,才會在每個要求中檢查。
如果可呼叫的觸發事件遭到叫用,但因未處理的例外狀況而失敗,或傳回失敗的承諾,要求會遭到
500 Internal Server Error
拒絕,並傳回INTERNAL
錯誤代碼。這可以避免使用者意外看見程式設計錯誤。如果叫用可呼叫函式,並使用為可呼叫函式提供的 API 傳回明確的錯誤情況,則要求會失敗。系統會根據 code.proto 中定義的錯誤狀態與 HTTP 狀態官方對應,傳回 HTTP 狀態碼。系統會在回應主體中編碼特定錯誤代碼、訊息和詳細資料,詳情請參閱下文。也就是說,如果函式傳回狀態為
OK
的明確錯誤,則回應的狀態為200 OK
,但回應中會設定error
欄位。如果用戶端觸發事件成功,回應狀態為
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 對應格式,用於錯誤,並包含status
、message
和 (選用)details
欄位。請勿納入code
欄位。如果status
欄位未設定或為無效值,用戶端應根據 code.proto 將狀態視為INTERNAL
。如果有details
,則會納入用戶資訊,並附加至用戶端 SDK 中的錯誤 (如適用)。
注意:此處的details
欄位是使用者提供的值。不一定是按 Proto 類型鍵入的值清單,如 GoogleStatus
格式。result
:函式傳回的值。可以是任何有效的 JSON 值。firebase-functions SDK 會自動將使用者傳回的值編碼為 JSON 格式。根據下列說明的序列化格式,用戶端 SDK 會自動將這些參數解碼為原生類型。
如果有其他欄位,系統會忽略這些欄位。
序列化
無論是要求還是回應,任意資料酬載的序列化格式都相同。
為確保平台一致性,這些值會使用 標準 JSON 對應,以 JSON 編碼方式編碼,就如同 proto3 通訊協定緩衝區中 Any
欄位的值一樣。簡單類型的值 (例如 null
、int
、double
或 string
) 會直接編碼,且不包含明確的類型。因此,float
和 double
的編碼方式相同,您可能不知道通話另一端收到的是哪一個。針對非 JSON 原生的型別,則會使用該值的型別 proto3 編碼。詳情請參閱 Any JSON 編碼的說明文件。
可使用的類型如下:
- 空值 -
null
- int (有符號或無符號,最多 32 位元) - 例如
3
或-30
。 - 浮點值 - 例如
3.14
- 雙重 - 例如:
3.14
- 布林值 -
true
或false
- 字串 - 例如
"hello world"
- map<string, any=""> - 例如
{"x": 3}
</string,> - 清單
- 例如: [1, 2, 3]
- long (有符號或無符號,最多 64 位元) - [詳情請參閱下文]
系統不支援 float
和 double
的 NaN
和 Infinity
值。
請注意,long
是 JSON 中通常不允許的特殊類型,但已包含在 proto3 規格中。例如,這些項目會編碼為:
long
{
'@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
欄位的地圖,系統會將其保留為地圖。這可讓開發人員在返回值中加入具有新類型的欄位,而不會破壞舊版用戶端。
程式碼範例
本節的範例說明如何編碼以下項目:
- 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"
}
}
}