Firebase Local Emulator Suite is an environment that allows you to emulate components of your Firebase project such as Firestore and Cloud Functions in your local environment. https://firebase.google.com/docs/emulator-suite?hl=ja
In this article, I would like to build the above environment using Docker and Docker Compose.
The code used in this article is here.
First, let's create a Firebase project. https://console.firebase.google.com/ It is required to use the Emulator Suite UI (console that can manage the emulator on the GUI) described later. Make a note of the ID of your project in the .env file.
$ mkdir empty_dir && cd empty_dir
$ touch .env
.env
GCP_PROJECT_ID=YOUR_PROJECT_ID
Let's create it from the Dockerfile immediately. Create an image to meet the operating requirements of the emulator. https://firebase.google.com/docs/emulator-suite/install_and_configure?hl=ja
$ mkdir docker
$ touch ./docker/firebase.dockerfile
docker/firebase.dockerfile
FROM ubuntu:20.04
RUN apt-get update -y
RUN apt-get install -y curl openjdk-11-jre-headless
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
&& apt-get install -y nodejs
RUN npm install -g firebase-tools
Next, create a Docker Compose configuration file. Create a directory as appropriate to mount the volume.
$ mkdir firebase
$ touch docker-compose.yaml
docker-compose.yaml
version: "3"
networks:
backend:
services:
workspace:
image: golang:1.15
environment:
FIRESTORE_EMULATOR_HOST: "firebase:8080"
GCP_PROJECT_ID: "${GCP_PROJECT_ID}"
volumes:
- ./gopath/:/go:cached
- ./workspace/:/opt/workspace:cached
ports:
- 8000:8000
working_dir: /opt/workspace
networks:
- backend
command: bash
tty: true
firebase:
build:
context: ./docker
dockerfile: firebase.dockerfile
volumes:
- ./firebase/emulators/:/opt/workspace:cached
- ./firebase/bin/:/root/.cache:cached
- ./firebase/config/:/root/.config:cached
ports:
- 4000:4000 # Emulator Suite UI
- 5000:5000 # Firebase Hosting
- 5001:5001 # Clound Functions
- 9000:9000 # Realtime Database
- 8080:8080 # Cloud Firestore
- 8085:8085 # Cloud Pub/Sub
working_dir: /opt/workspace
networks:
- backend
command: bash
tty: true
This time I would like to hit the Firestore API from Go language.
go:./workspace/go.mod
module github.com/kyhei/firebase_emu_sample
go 1.15
require (
cloud.google.com/go/firestore v1.3.0
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 // indirect
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f // indirect
golang.org/x/tools v0.0.0-20200904185747-39188db58858 // indirect
google.golang.org/api v0.31.0 // indirect
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d // indirect
)
go:./workspace/main.go
package main
import (
"context"
"log"
"os"
"cloud.google.com/go/firestore"
)
func main() {
ctx := context.Background()
client, err := firestore.NewClient(ctx, os.Getenv("GCP_PROJECT_ID"))
defer client.Close()
if err != nil {
log.Fatal(err.Error())
}
doc, _, err := client.Collection("users").Add(ctx, map[string]interface{}{
"name": "kyhei",
"age": 123,
})
if err != nil {
log.Fatal(err.Error())
}
log.Println(doc.ID)
q := client.Collection("users").Select("name", "age")
docs, err := q.Documents(ctx).GetAll()
if err != nil {
log.Fatal(err.Error())
}
for _, doc := range docs {
log.Println(doc.Data())
}
}
Let's run Docker Compose with the contents so far.
$ docker-compose up -d
$ docker-compose ps
It is OK if two containers are running.
Log in to the firebase container and initialize your Firebase project.
$ docker-compose exec firebase bash
root@da35c7925947:/opt/workspace# firebase login --no-localhost
root@da35c7925947:/opt/workspace# firebase init
In firebase init
, select an existing project and
Select Emulators as the service option. (Anything else is OK.)
Check all emulators in Emulators Setup
!
After that, you will be asked for the settings for each, but all are okay by default.
After the initialization is complete, edit firebase.json
.
json:./firebase/emulators/firebase.json
{
"emulators": {
"functions": {
"host": "0.0.0.0",
"port": 5001
},
"firestore": {
"host": "0.0.0.0",
"port": 8080
},
"database": {
"host": "0.0.0.0",
"port": 9000
},
"hosting": {
"host": "0.0.0.0",
"port": 5000
},
"pubsub": {
"host": "0.0.0.0",
"port": 8085
},
"ui": {
"enabled": true,
"host": "0.0.0.0",
"port": 4000
}
}
}
Now let's actually start the emulator with the following command.
root@da35c7925947:/opt/workspace# firebase emulators:start
The first time the executable file is downloaded. When the emulator starts up, it's OK if you can access the console with [http: // localhost: 4000](http: // localhost: 4000)!
Let's execute the script created in the previous section and check the connection to Firestore.
$ docker-compose exec workspace bash
root@c64fed9c2890:/opt/workspace# go run main.go
2020/09/09 07:17:08 6WQVScx2NGm4oli8f7iw
2020/09/09 07:17:08 map[age:123 name:kyhei]
If you check the console, you can see that the document has been added successfully.
Thank you for your hard work!
In order to start Cloud Functions and Hosting, each initialization is required. Initialization commands etc. are instructed from the log when the emulator starts, so it is OK if you execute them.
Recommended Posts