Firebase Local Emulator Suiteを使うぞ！


## こんにちは

新卒エンジニアの@Gardenia-710ことおびわんです。

この記事は[All About（株式会社オールアバウト） Advent Calendar 2023](https://qiita.com/advent-calendar/2023/allabout)の投稿です。

## Firebase使っていますか？

認証や簡易的なストレージ等のバックエンドの機能が簡単に使えるのがFirebaseのいいところで、弊社のプロダクトでも使用例があります。

しかし、この便利なFirebaseですが、チームで開発していると問題が発生します。

## チームでFirebaseを使うと

例えば、チャット機能のあるアプリケーションにおいて、チャットルームに送信されたメッセージをRealtime Databaseに保存して、チャットルーム内のメッセージ数をMySQL等のDBで管理しているとします。

チームのAさんがチャットルーム1番を作成し、メッセージを投稿したとします。

これによりRealtime Databaseには、`room/1/0001`というような階層でデータが保存され、AさんのローカルのDBにはチャットルーム1のメッセージ数は1であると記録されます。

続いてメンバーのBさんも新規作成ボタンから作成したら、当然BさんのDBにはチャットルーム1が存在しないため、チャットルーム1が作成されます。

するとBさんが新規作成したばかりの、メッセージ0件のチャットルームを開くと知らないメッセージがすでに存在するという状況になるわけです。

これくらいのメッセージアプリではそこまで困ることも少ないかもしれませんが、例えばルーム作成時に自動的に案内メッセージが投稿されるというような仕組みである場合、その案内メッセージデバッグ時に不都合が生じることもあります。

## じゃあどうするのか？

ということでこのような状況を改善するには、Firebaseの環境もローカルに立ち上げてしまえば良い。

ということでFirebase Local Emulator Suiteというものがあります。

今回はこの環境を構築して、Firebase Realtime Databaseをローカル環境で立ち上げられるようにしていきたいと思います！

## 環境を立ち上げよう

### 必要な環境について

ドキュメントによると以下のインストールが必須なのでまずはそれぞれインストールします。

- Node.js バージョン 16.0 以降
- Java JDK バージョン 11 以降

続いて、Firebase CLIをインストールします。ドキュメント記載の以下のスクリプトを実行します。

```bash
curl -sL https://firebase.tools | bash
```

インストールが完了したら、ログインします。

```bash
firebase login
```

ブラウザが立ち上がってGoogleアカウントでのログインが求められますのでログインします。

```bash
firebase projects:list
```

を実行してプロジェクトの一覧が出ればOKです！

### Firebaseプロジェクトの設定

次にFirebaseプロジェクト用のディレクトリを適当に作成し、Firebaseプロジェクトの初期化を行っていきます。

```bash
$ firebase init

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

You're about to initialize a Firebase project in this directory:

  /Users/user_name/app-projects/firebase
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. (Press
<space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
 ◯ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ◯ Hosting: Set up GitHub Action deploys
 ◯ Storage: Configure a security rules file for Cloud Storage
❯◉ Emulators: Set up local emulators for Firebase products
 ◯ Remote Config: Configure a template file for Remote Config
 ◯ Extensions: Set up an empty Extensions manifest
 ◯ Frameworks: Get started with Frameworks projects.
(Move up and down to reveal more choices)
```

エミュレーターが使いたいので、`Emulators`の部分でスペースを押してエンターキーで選択します。

使用するプロジェクト等を聞かれますので、必要に応じて選択します。

今回使用したいのはDatabase Emulatorなので選択します。

```bash
=== Emulators Setup
? Which Firebase emulators do you want to set up? Press Space to select emulators, then Enter to confirm your choices. (Press <space> to select,
<a> to toggle all, <i> to invert selection, and <enter> to proceed)
 ◯ Authentication Emulator
 ◯ Functions Emulator
 ◯ Firestore Emulator
❯◉ Database Emulator
 ◯ Hosting Emulator
 ◯ Pub/Sub Emulator
 ◯ Storage Emulator
(Move up and down to reveal more choices)
```

その後の質問も良い感じに答えてあげて、完了です。

### 起動しよう

ここまでくればもう完成です。

最後に

```bash
firebase emulators:start
```

でエミュレーターを起動します。すると。

```bash
$ firebase emulators:start
i  emulators: Starting emulators: database
⚠  database: Did not find a Realtime Database rules file specified in a firebase.json config file. The emulator will default to allowing all reads and writes. Learn more about this option: https://firebase.google.com/docs/emulator-suite/install_and_configure#security_rules_configuration.
i  database: Database Emulator logging to database-debug.log
i  ui: Emulator UI logging to ui-debug.log

┌─────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! It is now safe to connect your app. │
│ i  View Emulator UI at http://127.0.0.1:4000/               │
└─────────────────────────────────────────────────────────────┘

┌──────────┬────────────────┬────────────────────────────────┐
│ Emulator │ Host:Port      │ View in Emulator UI            │
├──────────┼────────────────┼────────────────────────────────┤
│ Database │ 127.0.0.1:9000 │ http://127.0.0.1:4000/database │
└──────────┴────────────────┴────────────────────────────────┘
  Emulator Hub running at 127.0.0.1:4400
  Other reserved ports: 4500

Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.
```

という感じで情報が表示されますので、[localhost:4000](http://localhost:4000)へアクセスすると・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102723/af4c8ac2-c882-f761-ecdb-f6a518a5394d.png)

すばらしい！エミュレーターの管理画面が表示されました！

本命のReltime Database Emulatorを開けば、見慣れたあの画面が表示されます！(firebaseとfirebase-testが表示されているのは色々いじった後なので通常は表示されません)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102723/cb388fb6-3efd-9bd7-5611-e653f02977b9.png)

これでチーム内で一つのDBを参照することによるデータ不整合を防ぐことができます！

また、Github Actionsなどを使用している場合、CIでのテスト時にこのエミュレーターを用いることもできます！

さぁ、Firebase Local Emulator Suiteを使って快適なチーム開発を行いましょう！

## 参考

- [Firebase ローカル エミュレータ スイートの概要（公式ドキュメント）](https://firebase.google.com/docs/emulator-suite?hl=ja)