https.onCall のプロトコル仕様

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-Instance-ID-Token: <iid>
    • Firebase クライアント SDK の FCM 登録トークンです。これには文字列を設定する必要があります。またハンドラの context で使用できます。プッシュ通知のターゲティングのために使用されます。
  • 省略可: X-Firebase-AppCheck: <token>
    • リクエストを行うクライアント アプリによって提供される Firebase App Check トークンです。バックエンドではハンドラの contextappId を挿入し、このトークンの検証とデコードを自動で処理します。トークンが検証されない場合、リクエストは拒否されます(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. 呼び出し可能なトリガーが呼び出されたにもかかわらず、処理不能な例外で失敗したり、失敗 Promise を返したりした場合、リクエストは 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 オブジェクトです。少なくとも、result または error のいずれか一方と、オプションのフィールドが含まれています。レスポンスが 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 は、以下で説明するシリアル化形式に従って、これらのパラメータを自動的にネイティブ型にデコードします。

他のフィールドが存在する場合は無視されます。

シリアル化

任意のデータ ペイロードのシリアル化形式は、リクエストとレスポンスの両方で同じです。

プラットフォームでの整合性を保つ目的で、これらは proto3 プロトコル バッファ内の Any フィールド値であるかのように JSON でエンコードされ、その際に標準の JSON マッピングが使用されます。nullintdoublestring などの単純型の値は直接エンコードされ、それらに明示的な型は含まれません。したがって、floatdouble が同じ方法でエンコードされるため、呼び出しの相手側でどちらで受信されたかが不明になる場合があります。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 ビット)- [詳細は下記を参照]

floatdouble の場合、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 になり、shortint になります。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"
        }
    }
}