【AI Shift Advent Calendar 2021】ローカル開発用のFirestoreエミュレーターにGoで疎通してみる

こんにちは、Development Team の水谷です。
本記事は AI Shift Advent Calendar 2021 の19日目の記事です。

私たちはFirestoreを局所的に利用しており、今回はローカル開発用にエミュレーターを用意し、データ格納をGoで行ってみます。

まずは、下準備から始めていきましょう。

CLI をインストールする

公式ドキュメントのFirebase CLI をインストールするを参考に、firebase-toolsのインストールを行いましょう。

$ npm install -D firebase-tools
$ firebase login

プロジェクトを初期化する

次に、Firebase プロジェクトを初期化するを参考に、以下コマンドで初期化していきましょう。

$ firebase init

使いたいサービスを対話形式で尋ねられるので、今回はFirestoreのみ選択しています。
このコマンドによって、設定ファイル(firebase.json)が作られ、このファイルを通して管理ができるようです。

エミュレーターを起動する

エミュレータの起動を参考に、エミュレータを起動しましょう。

$ firebase emulators:start --project=test-project --only=firestore

今回、--projectには任意の文字列(test-project)を渡しています。このプロジェクトIDは、GOのコードで後ほど利用します。

また、--onlyオプションには,(カンマ)区切りで以下のサービスを指定できるようです。

  • auth
  • database
  • firestore
  • functions
  • hosting
  • pubsub

さて実際に起動すると、以下の出力がされました。

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

┌───────────┬────────────────┬─────────────────────────────────┐
│ Emulator  │ Host:Port      │ View in Emulator UI             │
├───────────┼────────────────┼─────────────────────────────────┤
│ Firestore │ localhost:8080 │ http://localhost:4000/firestore │
└───────────┴────────────────┴─────────────────────────────────┘
  Emulator Hub running at localhost:4400
  Other reserved ports: 4500

上記にアクセスすると、GUIで諸々閲覧できそうで、便利そうです。

Firebaseのエミュレータ一覧
FirestoreのGUIツール

Goを用いてドキュメントを格納してみる

さて、ローカルにFirestoreのエミュレーターが起動できたので、最後にデータを格納してみましょう。今回はクライアントとして、Goのcloud.google.com/go/firestoreパッケージを利用します。

上記リンクに記載されるOverviewに、Google Cloud Firestore Emulatorという項目があり、環境変数としてFIRESTORE_EMULATOR_HOSTが必要な旨が記載されているので、その通り実行していきましょう。

以下がGoの実装となります。

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"cloud.google.com/go/firestore"
)

const HostEnvKey = "FIRESTORE_EMULATOR_HOST"
const Project = "test-project"

func main() {
	// Checking ENV
	_, exist := os.LookupEnv(HostEnvKey)
	if !exist {
		log.Fatalf("required env %s", HostEnvKey)
	}

	// Store
	ctx := context.Background()
	client, _ := firestore.NewClient(ctx, Project)
	doc, _, err := client.
		Collection("developer").
		Add(ctx, map[string]interface{}{
			"name":    "john",
			"age":     "20",
			"message": "Hello World",
		})

	if err != nil {
		log.Fatal(err)
	}

	// Success Message
	successMsg := fmt.Sprintf("Store is success, 'doc.ID' is %s, 'doc.Path' is %s", doc.ID, doc.Path)
	log.Println(successMsg)
}

FIRESTORE_EMULATOR_HOSTの環境変数を設定し、実行してみましょう。

$ export FIRESTORE_EMULATOR_HOST=localhost:8080
$ go run main.go
// Store is success, 'doc.ID' is ...

GUIを確認すると、データ格納が実際にできてる点を確認できます。無事にローカルでFirestoreのエミュレーターを起動し、Goで疎通することに成功しました。

FirestoreのGUI(データが格納されている様子)

終わりに

FirestoreのGUIが含まれる公式Dockerイメージがあると助かるのですが、現状見つけることができませんでした。

なので、上記エミュレーターの実行環境を、今後はDockerイメージにすることで開発メンバーが、ローカルで起動しやすい環境を整備していこうと思います。

Firestoreユーザに役立てば幸いです。最後まで読んで頂きありがとうございました!