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 傳送推播通知,否則系統不會在每個要求中檢查權杖。
如果叫用可呼叫的觸發程序,但因未處理的例外狀況而失敗,或傳回失敗的 Promise,系統會以
500 Internal Server Error
拒絕要求,並傳回INTERNAL
的錯誤代碼。以免程式碼錯誤不慎暴露給使用者。如果叫用可呼叫函式並使用為可呼叫函式提供的 API 傳回明確的錯誤情況,要求就會失敗。傳回的 HTTP 狀態碼是根據 code.proto 中定義的錯誤狀態與 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
是否也存在,要求都會視為失敗。這個欄位的值應為標準 Google Cloud HTTP 對應格式的錯誤 JSON 物件,並包含status
、message
和 (選用)details
的欄位。不得包含code
欄位。如果status
欄位未設定或值無效,用戶端應根據 code.proto 將狀態視為INTERNAL
。如果存在details
,則會視情況納入附加至用戶端 SDK 錯誤的任何使用者資訊。
注意:此處的details
欄位是使用者提供的值。這不一定是 GoogleStatus
格式中以原型為鍵的值清單。result
- 函式傳回的值。可以是任何有效的 JSON 值。firebase-functions SDK 會自動將使用者傳回的值編碼為這種 JSON 格式。用戶端 SDK 會根據下述序列化格式,自動將這些參數解碼為原生型別。
如果還有其他欄位,請忽略。
序列化
要求和回應的任意資料酬載序列化格式相同。
為確保平台一致性,這些值會以 JSON 格式編碼,如同 proto3 通訊協定緩衝區中的 Any
欄位值,並使用標準 JSON 對應。系統會直接編碼 null
、int
、double
或 string
等簡單型別的值,且不會包含明確型別。因此,float
和 double
的編碼方式相同,您可能不知道通話另一端收到的是哪個字元。如果類型不是 JSON 原生類型,系統會使用值的型別 proto3 編碼。詳情請參閱 Any JSON 編碼說明文件。
允許的類型如下:
- null -
null
- int (有符號或無符號,最多 32 位元) - 例如
3
或-30
。 - 浮點數 - 例如
3.14
- 雙引號 - 例如
3.14
- 布林值 -
true
或false
- 字串 - 例如
"hello world"
- map<string, any=""> - e.g.
{"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'
}
unsigned long
{
'@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"
}
}
}