🔖

開発・テスト用にFirestoreエミュレータをセットアップする

2025/01/14に公開

はじめに

本記事では、開発・テスト用のFirestoreエミュレータのセットアップ方法について解説します。
テストデータはNode.jsでセットすることを想定しています。
最後に、手動でデータを編集した際の永続化方法も記載しています。

本記事で紹介する手順は以下の通りです。

  1. Firebase Local Emulator Suiteをコンテナ内で立ち上げる
    • ブラウザから確認できるUIとFirestoreを使用できるように設定
  2. 別のNode.jsのコンテナから、Firestoreにテストデータをセットする
  3. ブラウザからテストデータを確認する
  4. エミュレータで編集したデータを永続化する

参考までに、本記事で紹介する手順では以下のような構成でファイルを作成します。(データの永続化部分は除いています。)

work-dir
├── docker-compose.yaml
├── firebase
│   ├── Dockerfile
│   └── firebase.json
└── app
    ├── Dockerfile
    └── test.ts

Firebase Local Emulator Suiteのコンテナの準備

公式ページを参考にして設定ファイルとDockerfileを用意していきたいと思います。

https://firebase.google.com/docs/emulator-suite/install_and_configure?hl=ja

まず「firebase」ディレクトリを作り、その配下に以下のファイルを用意してください。

Dockerfile
FROM node:20.18.0-slim

RUN apt-get update && apt-get install -y wget gnupg \
    && wget -O - https://apt.corretto.aws/corretto.key | gpg --dearmor -o /usr/share/keyrings/corretto-keyring.gpg \
    && echo "deb [signed-by=/usr/share/keyrings/corretto-keyring.gpg] https://apt.corretto.aws stable main" |  tee /etc/apt/sources.list.d/corretto.list \
    && apt-get update && apt-get install -y java-17-amazon-corretto-jdk

RUN npm install -g firebase-tools
.firebaserc
{
  "projects": {
    "default": "test-project"
  }
}
firebase.json
{
  "emulators": {
    "ui": {
      "host": "0.0.0.0",
      "port": 4000
    },
    "firestore": {
      "host": "0.0.0.0",
      "port": 8080
    }
  }
}

エミュレータの動作にはNode.jsとOpenJDKが必要になります。

OpenJDKは以下のページを参考にしてAmazon Correttoを採用しています。

https://docs.aws.amazon.com/ja_jp/corretto/latest/corretto-17-ug/generic-linux-install.html

Node.jsでテストデータをセットするための準備

「app」ディレクトリを作り、その配下に以下のファイルを用意してください。

Dockerfile
FROM node:20.18.0-slim

WORKDIR /app
RUN npm install ts-node firebase-admin 
RUN ./node_modules/.bin/tsc --init
test.ts
import { getApps, initializeApp } from "firebase-admin/app"
import { getFirestore } from "firebase-admin/firestore"

if (getApps().length === 0) {
  initializeApp({ projectId: "test-project" })
}

const firestore = getFirestore()

firestore
  .collection("test-collection")
  .doc("1")
  .set({ id: "test-id", body: "test data" })

今回はts-nodeでテストデータをセットしていきます。

docker-composeファイルを準備

作業しているディレクトリの直下に以下のファイルを用意してください。

docker-compose.yaml
services:
  firebase-emulator:
    build:
      context: .
      dockerfile: ./firebase/Dockerfile
    container_name: firebase-emulator
    ports:
      - 4000:4000
      - 8080:8080
    volumes:
      - ./firebase/.firebaserc:/firebase/.firebaserc
      - ./firebase/firebase.json:/firebase/firebase.json
    tty: true
    working_dir: /firebase
    command: firebase emulators:start
  app:
    build:
      context: .
      dockerfile: ./app/Dockerfile
    container_name: app
    depends_on:
      - firebase-emulator
    environment:
      FIRESTORE_EMULATOR_HOST: "firebase-emulator:8080"
    volumes:
      - ./app/test.ts:/app/test.ts
    working_dir: /app
    command: npx ts-node test.ts

環境変数 FIRESTORE_EMULATOR_HOST を設定することでエミュレータへ接続してくれるようになります。
今回はコンテナ間の通信ですので firebase-emulator:8080 としていますが、ローカル環境で全て完結させる場合は localhost:8080 のようになるかと思います。
(他のサービスとポートが重複しないようにご注意ください!もしポートを変更したい場合は、firebase.jsonとdocker-compose.yamlのポートを変更してください。)

Firebase Local Emulator Suiteを起動

以下のコマンドを実行して、各コンテナを起動します。

docker compose up

コンテナを起動した後、ブラウザでhttp://127.0.0.1:4000/にアクセスします。

以下のような画面が確認できれば成功です。

以下のように「Firestore emulator」の画面でもテストデータのセットが成功していることを確認できると思います。

ブラウザからFirestoreを編集して、その値を永続化して使用する

ここからはブラウザでFirestoreの値を編集して、その値を永続化して使用する方法を記載します。

まず、docker-compose.yamlを以下の通り編集して、先程と同様に docker compose up でコンテナを起動します。

docker-compose.yaml
services:
  firebase-emulator:
    build:
      context: .
      dockerfile: ./firebase/Dockerfile
    container_name: firebase-emulator
    ports:
      - 4000:4000
      - 8080:8080
    volumes:
    # データ永続化用のvolumeを追記
      - ./firebase/data:/firebase/data
      - ./firebase/.firebaserc:/firebase/.firebaserc
      - ./firebase/firebase.json:/firebase/firebase.json
    tty: true
    working_dir: /firebase
    command: firebase emulators:start
  app:
    build:
      context: .
      dockerfile: ./app/Dockerfile
    container_name: app
    depends_on:
      - firebase-emulator
    environment:
      FIRESTORE_EMULATOR_HOST: "firebase-emulator:8080"
    volumes:
      - ./app/test.ts:/app/test.ts
    working_dir: /app
    command: npx ts-node test.ts

ブラウザ上のFirestoreで値を編集します。

今回はテストデータのbodyを「test data change」と編集してみました。

ブラウザでFirestoreの値を編集した後、以下のコマンドを実行してFirebaseのエミュレータのデータをexportします。
(2度目のエクスポートの際にデータを上書きするかどうか選択する必要があります。「--force」オプションは、その選択を省略するために付けています。)

docker exec firebase-emulator firebase emulators:export ./data/emulator-data --force

次にdocker-compose.yamlを以下の通り編集します。

docker-compose.yaml
services:
  firebase-emulator:
    build:
      context: .
      dockerfile: ./firebase/Dockerfile
    container_name: firebase-emulator
    ports:
      - 4000:4000
      - 8080:8080
    volumes:
      - ./firebase/data:/firebase/data
      - ./firebase/.firebaserc:/firebase/.firebaserc
      - ./firebase/firebase.json:/firebase/firebase.json
    tty: true
    working_dir: /firebase
    # 起動時にexportしたデータをimportしてくれるようになる
    command: firebase emulators:start --import ./data/emulator-data
  app:
    build:
      context: .
      dockerfile: ./app/Dockerfile
    container_name: app
    depends_on:
      - firebase-emulator
    environment:
      FIRESTORE_EMULATOR_HOST: "firebase-emulator:8080"
    volumes:
      - ./app/test.ts:/app/test.ts
    working_dir: /app
    command: npx ts-node test.ts

最後に以下のコマンドでfirebaseのコンテナを起動します。
(もし、appコンテナも実行したい場合は、「docker compose up」で各コンテナを起動してください。ただ、その場合はデータがtest.tsの内容で更新されてしまいます。)

docker compose up firebase-emulator

そうすれば、先程exportしたデータを読み込んで起動してくれるようになります。

Aprender Tech Blog

Discussion