Cloud Functions の https.onCall
トリガーは、リクエストとレスポンスが特定の形式をした HTTPS トリガーです。このセクションでは、API を実装するためにクライアント SDK で使用する 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 トークンです。バックエンドではハンドラの
context
にappId
を挿入し、このトークンの検証とデコードを自動で処理します。トークンが検証されない場合、リクエストは拒否されます(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 ステータス コードは、HTTP ステータスとエラー ステータスの正式なマッピングに基づいています(このマッピングは code.proto で定義されています)。返される具体的なエラーコード、メッセージ、詳細情報は、以下で説明するように、レスポンス本文にエンコードされます。これは、ステータスが
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
フィールドはユーザー指定の値です。Google のStatus
形式のような、プロトタイプによりキー付けされる値のリストになるとは限りません。result
- 関数により返される値です。これには任意の有効な JSON 値を使用できます。firebase-functions SDK は、ユーザーが返した値を、この JSON 形式に自動的にエンコードします。クライアント SDK は、以下で説明するシリアル化形式に従って、これらのパラメータを自動的にネイティブ型にデコードします。
他のフィールドが存在する場合は無視されます。
シリアル化
任意のデータ ペイロードのシリアル化形式は、リクエストとレスポンスの両方で同じです。
プラットフォームでの整合性を保つ目的で、これらは proto3 プロトコル バッファ内の Any
フィールド値であるかのように JSON でエンコードされ、その際に標準の JSON マッピングが使用されます。null
、int
、double
、string
などの単純型の値は直接エンコードされ、それらに明示的な型は含まれません。したがって、float
と double
が同じ方法でエンコードされるため、呼び出しの相手側でどちらで受信されたかが不明になる場合があります。JSON のネイティブではない型の場合、型指定の proto3 エンコードが使用されます。詳しくは、JSON エンコードに関するドキュメントをご覧ください。
次の型を使用できます。
- null -
null
- int(符号付きまたは符号なし、最大 32 ビット)- 例:
3
または-30
。 - float - 例:
3.14
- double - 例:
3.14
- boolean -
true
またはfalse
- string - 例:
"hello world"
- map<string, any=""> - 例:
{"x": 3}
</string,> - list
- 例: [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"
}
}
}