Firestore エミュレータを使用して Datastore モードをテストする

Google Cloud CLI には、Datastore モードの Firestore アプリケーションのテストに使用できる Firestore 用のローカル インメモリ エミュレータが用意されています。エミュレータは、すべての Datastore モード クライアント ライブラリで使用できます。 エミュレータはローカルテストでのみ使用してください。

--database-mode=datastore-modegcloud emulators firestore を使用して、Datastore モードの Firestore の動作をテストします。

本番環境でのデプロイにはエミュレータを使用しないでください。エミュレータはメモリ内にのみデータを保存するため、終了時にデータは失われます。

エミュレータをインストールする

Firestore エミュレータをインストールするには、gcloud CLI をインストールして更新します。

  1. gcloud CLI をインストールします

  2. gcloud CLI インストールを更新して、最新の機能を取得します。

    gcloud components update
    

エミュレータを実行する

  1. 次のコマンドを実行して、エミュレータを起動します。

    gcloud emulators firestore start --database-mode=datastore-mode
    

    エミュレータによって、実行中のホストとポート番号が表示されます。

    デフォルトでは、エミュレータは 127.0.0.1:8080 の使用を試みます。エミュレータを特定のホストとポートにバインドするには、オプションの --host-port フラグを使用し、HOSTPORT を置き換えます。

    gcloud emulators firestore start --database-mode=datastore-mode --host-port=HOST:PORT
    
  2. キーボード ショートカット Control + C を使用してエミュレータを停止します。

エミュレータに接続する

クライアント ライブラリとアプリをエミュレータに接続するには、DATASTORE_EMULATOR_HOST 環境変数を設定します。この環境変数が設定されると、クライアント ライブラリは自動的にエミュレータに接続されます。

export DATASTORE_EMULATOR_HOST="HOST:PORT"

エンティティをエミュレータにインポートする

エミュレータのインポート機能を使用することによって、一連のエンティティ エクスポート ファイルからエミュレータにエンティティを読み込むことができます。エンティティ エクスポート ファイルは、Datastore モードのデータベースのエクスポートまたはエミュレータ インスタンスから取得できます。

エンティティをエミュレータにインポートするには、2 つの方法があります。1 つ目の方法は、エミュレータの起動コマンドにフラグ import-data を追加することです。2 つ目の方法は、POST インポート リクエストをエミュレータに送信することです。curl や同様のツールを使用します。次の例を参照してください。

プロトコル

curl -X POST http://localhost:8080/emulator/v1/projects/[PROJECT_ID]:import \
-H 'Content-Type: application/json' \
-d '{"database":"[DATABASE]", "export_directory":"[EXPORT_DIRECTORY]"}'
エミュレータが別のポートを使用している場合は、localhost:8080 を変更してください。

CLI のフラグ

gcloud emulators firestore start --database-mode=datastore-mode --import-data=[EXPORT_DIRECTORY]

ここで

  • [PROJECT_ID] は、プロジェクトの ID です。
  • [DATABASE] は、データベース パスです。たとえば、デフォルトのデータベースを使用するプロジェクトは次のようになります。

    {"database":"projects/myProject/databases/"}

  • [EXPORT_DIRECTORY] は、エンティティ エクスポート ファイルの overall_export_metadata ファイルへのパスです。次に例を示します。

    {"export_directory":"/home/user/myexports/2024-03-26T19:39:33_443/2024-03-26T19:39:33_443.overall_export_metadata"}

エミュレータ内のエンティティをエクスポートする

エミュレータのエクスポート機能を使用することによって、エミュレータ内のエンティティを一連のエンティティ エクスポート ファイルに保存できます。その後、インポート オペレーションを使用して、エンティティ エクスポート ファイル内のエンティティを Datastore モードのデータベースまたはエミュレータ インスタンスに読み込むことができます。

エミュレータからエンティティをエクスポートするには、2 つの方法があります。1 つ目の方法は、エミュレータの起動コマンドにフラグ export-on-exit を追加することです。2 つ目の方法は、POST エクスポート リクエストをエミュレータに送信することです。curl や同様のツールを使用します。次の例を参照してください。

プロトコル

curl -X POST http://localhost:8080/emulator/v1/projects/[PROJECT_ID]:export \
-H 'Content-Type: application/json' \
-d '{"database":"[DATABASE_PATH]", "export_directory":"EXPORT_DIRECTORY"}'
エミュレータが別のポートを使用している場合は、localhost:8080 を変更してください。

CLI のフラグ

gcloud emulators firestore start --database-mode=datastore-mode --export-on-exit=EXPORT_DIRECTORY

ここで

  • [PROJECT_ID] は、プロジェクトの ID です。
  • [DATABASE_PATH] は、データベース パスです。たとえば、デフォルトのデータベースを使用するプロジェクトは次のようになります。

    {"database":"projects/myProject/databases/"}

  • [EXPORT_DIRECTORY] は、エンティティ エクスポート ファイルを保存するディレクトリを指定します。このディレクトリには、一連のエンティティ エクスポート ファイルが含まれていないようにしてください。次に例を示します。

    {"export_directory":"/home/user/myexports/2024-03-26/"}

エミュレータ データをリセットする

Firestore エミュレータには、エミュレータ内のすべてのデータをリセットするための REST エンドポイントが含まれています。このエンドポイントを使用すると、エミュレータをシャットダウンせずにテスト間でデータを消去できます。

エミュレータ内のすべてのデータをリセットするには、次のエンドポイントに対して HTTP POST オペレーションを実行します。HOSTPORT は、選択したホストとポートに置き換え、PROJECT_ID は実際のプロジェクト ID に置き換えます。

http://HOST:PORT/reset

エミュレータで 127.0.0.1:8080 を使用しない場合は、ホストとポートを調整します。コードは、リセットが終了または失敗したことを REST が確認するまで待機します。

この操作は curl を使用してシェルから実行できます。

$ curl -X POST "http://HOST:PORT/reset"

エミュレータと本番環境の違い

エミュレータは、本番環境サービスの動作を忠実に再現しようとしますが、いくつか注意が必要な制限事項があります。

同時実行と整合性

エミュレータでは、ペシミスティック同時実行と強整合性のみがサポートされます。 エミュレータでは、オプティミスティック同時実行と結果整合性の設定はサポートされていません。

トランザクション

エミュレータは、本番環境で発生するトランザクションの動作すべてを実装しているわけではありません。1 つのドキュメントに対して複数の書き込みが同時に実行される機能をテストする場合、エミュレータでは書き込みリクエストが完了するまで時間がかかることがあります。場合によっては、ロックが解除されるまでに最長で 30 秒かかります。必要に応じて、この問題に対応するように、テストのタイムアウトを調整することを検討してください。

インデックス

このエミュレータでは複合インデックスは追跡されず、有効なクエリであればそのまま実行されます。実際の Datastore モードのインスタンスでアプリをテストし、必要なインデックスを特定してください。

上限

このエミュレータでは、本番環境で適用される制限すべてが適用されるわけではありません。たとえば、本番環境サービスではサイズが大きいことを理由に拒否されるトランザクションでも、エミュレータでは許容される場合があります。ドキュメントに記載されている制限を十分に理解し、事前にこうした制限を回避するようにアプリを設計してください。

次のステップ