docker-compose × Firebase Emulatorでローカル環境構築
※本記事はこちらのスライドを marp で変換して作成する元になった markdown ファイルです
Firebase の使いどころ
- オンライン家庭教師と、学生&親御さんが使うチャットに利用
- Web(Nuxt.js) ⇔ スマホアプリ(React Native)
- Firebase Auth & Firestore & Storage を利用
- ちなみに、Nuxt.js では composition-api を使って Firebase 用のフックを作成しています
- vue-composition-api で Firestore を扱う react-firebase-hooks 風の Composition Function を作った
- useDocument/useCollection みたいな感じ
課題
- 当時:ステージング用 Firebase を各開発者がローカルでも利用
- データやアカウント情報が混ざってややこしい
- Web バックエンド(MySQL + Laravel/NestJS)との連携
- MySQL で発行した uid をベースとしたカスタムトークン認証をやっているので、uid が各々の環境でかぶって混乱する
Emulator の概要
- CLI から擬似的な Firebase 環境を起動できる仕組み
- localhost はもちろん、コンテナ内や CI でも起動できる
- Auth/Firestore/Functions/Hosting 等に対応
主な利用用途
- Firestore のセキュリティルールのテスト
- docker-compose で共通の network を使うことで、MySQL が発行した uid を共通で利用するなどの連携ができる
Emulator セットアップの全体的な流れ
- Docker コンテナ作成
- Node.js コンテナの Dockerfile を書く
- docker-compose.yml で他コンテナのネットワークと接続
- コンテナを起動する
- bash で入り込み、エミュレータを起動する
- ソースコードの書き換え
- 環境変数を見て、Emulator の利用可否を分岐する
Docker コンテナ作成
FROM node:10-buster
RUN apt-get update -y
RUN apt-get install -y curl openjdk-11-jre-headless
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
&& apt-get install -y nodejs
RUN npm install -g firebase-tools && mkdir functions
COPY ./package.json ./
COPY ./yarn.lock ./
COPY ./functions/package.json ./functions/.
COPY ./functions/yarn.lock ./functions/.
docker-compose.yml
version: '3.7'
networks:
server:
external:
name: XXXXXX
services:
firebase:
build:
context: .
dockerfile: ./docker/local/Dockerfile
volumes:
- ./:/opt/workspace:cached
ports:
- 9099:9099 # Auth
- 4000:4000 # Emulator Suite UI
- 5001:5001 # Cloud Functions
- 8080:8080 # Cloud Firestore
environment:
USE_LOCAL_BACKEND: 1
working_dir: /opt/workspace
networks:
- server
command: bash -c 'yarn && cd functions && yarn && /bin/bash'
tty: true
docker-compose.yml ポイント
Web コンテナの docker-compose network と接続する
これにより http://nginx 等で Web に接続できるし、Web からも http://firebase:9099 等の URI で Emulator に接続できる
networks:
server:
external:
name: XXXXXX_default
Emulator の起動画面(Firestore)
データの Export/Import
以下のコマンドで Emulator 内のデータは出し入れできるので、
基本的なデータを入れたら Seeder 代わりに開発メンバー間で共有するのがおすすめ
firebase emulators:export ./data/export_my_data -P default
firebase emulators:start -P default --import=./data/export_my_data
フロントエンドから呼び出し
useAuth/useFirestore/useStorage(Storage は将来に期待)という命名で export
const enabledEmulator = () => process.env.USE_FIREBASE_EMULATOR
export const useAuth = () => {
auth = firebase.app().auth()
if (enabledEmulator()) {
auth.useEmulator('http://localhost:9099')
}
return auth
}
フロントエンドから呼び出し2
ざっくりこんな感じです
useAuth().onAuthStateChanged((user) => {
state.firebaseUser = user;
});
const collection: CollectionReference<Room> = useFirestore().collection(
"rooms"
);
バックエンド(例:NestJS)からの呼び出し
AdminSDK からの接続も Emulator 対応している
docker-compose で接続しているのでホスト名は firebase
import * as admin from "firebase-admin";
// ...
admin.firestore().settings({
host: "firebase:8080",
ssl: false,
});
React Native Emulator と接続
Nuxt⇔React Native 間でのリアルタイムチャットがローカル環境完結で実現できる!
Storage には未対応
- Auth/Firestore/Functions/Hosting に並んでよく使われていると思われる Storage には未対応
- つまり、Storage の動作確認をしたければそこだけステージングの Firebase に引き続きアップロードされる
- セキュリティルールとか、Function のテストとかは相変わらず生の Firebase を使わないといけない
- 各開発者が個人用の Firebase を持って運用するのも一案
所感
- 思ったより完成度が高かった
- 特に Firestore を hook にした Functions が動くのはちょっと感動
- Admin SDK も Emulator を向いて使える
- Auth は Custom Token を使った認証もいける
- 今後の課題
- Storage 対応
告知
私が CTO を務めている「オンライン家庭教師マナリンク」では、エンジニアを募集しております。
2020/11/28 現在、Web エンジニア及び、React Native エンジニアを探しております。
マナリンクでは、オンライン家庭教師という生き方を選択している先生方が稼げるように、サイト上で自身のプロフィールを魅力的に発信できるようにしたり、オンライン指導専用アプリをリリースするなど、次々にプロダクトを開発しています。エンジニアでいうフリーランスのような生き方を、教育関係者の方々にも提供することを目指す事業です。
日々新しい技術を勉強して、試す機会を探している方にはうってつけかな環境と思います。僕も、半年間 Next.js を個人で勉強し続けた結果、新規メディア立ち上げの機会を得て早速 Next.js でリリースができました。
興味あれば Twitter に DM 等でご連絡をください!
最後まで読んでいただきありがとうございました!記事が参考になったらバッジお願いします!
Discussion