Firebase AuthenticationをEmulatorで動かす
概要
すでにたくさん記事があるから書く必要はないが...
最近やったことをすぐに忘れちゃうおじさんなので
後で振り返るように全部書き出しておく!
直近の案件では認証にFirebase Authenticationを使ってたけど
ローカル環境でも実際のサービスにアクセスして認証行っててもったいない感が強かったので
ローカル開発用のdocker-compose環境にemulatorを導入してみた
Firebase Authentiationのservice作成
docker-composeの書きっぷり
こんな感じ。firebase serviceの方みてくだされ
version: '3.8'
services:
nextjs:
build:
context: ./frontend
dockerfile: ./docker/Dockerfile
container_name: frontend
volumes:
- ./frontend:/usr/src/app
- /usr/src/app/node_modules
command: "yarn dev"
ports:
- 3000:3000
firebase:
build: frontend/docker/firebase
container_name: firebase
ports:
- 4000:4000
- 9099:9099
volumes:
- ./frontend:/opt/workspace
working_dir: /opt/workspace
command: "firebase emulators:start --import=./firebase/data --export-on-exit --project ucwork"
tty: true
ポイントとしては以下
- 9099portが認証用
- 4000portが認証情報とかブラウザで見れる用
- emulatorの起動方法
-
--project ucwork
でGCP project idを指定- なんかこれ指定しないとコンテナ起動時こけちゃう
-
--import
指定でローカルユーザーデータとかの永続化- これしとくとコンテナ落としても登録したアカウント消えない
- 永続化ディレクトリはgit管理して中身のファイルはignoreしたいのでこのファイル追加
frontend/firebase/data/.gitignore# Ignore every files this directory * !.gitignore
-
Dockerfileの書きっぷり
java環境が必要らしいのでこんな感じ
FROM node:15.9.0-alpine3.13
RUN apk update \
&& apk --no-cache add openjdk11-jre-headless \
&& rm -rf /var/cache/apk/*
RUN npm install -g firebase-tools
firebase用の設定
firebase用の設定ファイル準備
これないとちゃんと動かないポイ
{
"emulators": {
"auth": {
"port": 9099,
"host": "0.0.0.0"
},
"ui": {
"enabled": true,
"host": "0.0.0.0",
"port": 4000
}
}
}
検証
docker-compose up -d --build
でコンテナ作成&起動して
http://localhost:4000/
にアクセスするとこんなemulatorが見えるはず
Emulatorにアクセスするフロントエンド
Firebaseの初期化
自分の環境はReact, Next.js, TypeScriptなのでこんな感じのファイル用意して初期化
ローカルのEmulatorだから実際のFirebase情報詰めたconfigとかいらないんじゃないの?
と思ったけど、これ入れて初期化しておかないと
apiKeyがないよって怒られるので設定しとく😫
(あの手この手で初期化やってみたけど抜け道を見つけられなかった😫
import firebase from "firebase/app";
import "firebase/auth";
const config = {
apiKey: process.env.FIREBASE_API_KEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
databeseURL: process.env.FIREBASE_DATABASE_URL,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MESSEGING_SENDER_ID,
appId: process.env.FIREBASE_APP_ID,
measurementId: process.env.FIREBASE_MEASUREMENT_ID,
};
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
if (process.env.NODE_ENV !== "production") {
const auth = firebase.auth();
auth.useEmulator(process.env.FIREBASE_AUTH_EMULATOR_URL);
}
export default firebase;
envファイルに必要な情報
Firebaseのconsoleでゲットできる情報を
こんな感じで詰めておく
FIREBASE_API_KEY=xxx
FIREBASE_AUTH_DOMAIN=xxx.firebaseapp.com
FIREBASE_PROJECT_ID=xxx
FIREBASE_STORAGE_BUCKET=xxx.appspot.com
FIREBASE_MESSEGING_SENDER_ID=xxx
FIREBASE_APP_ID=xxx
FIREBASE_MEASUREMENT_ID=xxx
FIREBASE_AUTH_EMULATOR_URL=http://localhost:9099
暗号化されてるとしてもGitHubにあげたくないので
アクセス制限されたGCSにファイルあげて、ローカル環境構築時にとってくるようにしてる。
(みんなenvファイルどう管理してるんだろ🧐
firebase使って認証
こんな感じでGoogleアカウント使ってログインする実装してみる
いらないこといっぱい書いてあるけど、ポイントはsignIn
のメソッドだけ
import { FC, useContext, Suspense } from "react";
import Link from "next/link";
import { useTranslation } from "react-i18next";
import firebase from "../services/firebase";
import styles from "../styles/Home.module.css";
import { AuthContext } from "../context/Auth";
import GoogleSignInButton from "../components/atoms/GoogleSignInButton";
import { Grid, CircularProgress } from "@material-ui/core";
const Home: FC = () => {
const [t] = useTranslation(["index"]);
const { state } = useContext(AuthContext);
const { currentUser } = state;
const signIn = async () => {
const provider = new firebase.auth.GoogleAuthProvider();
await firebase.auth().signInWithRedirect(provider);
};
return (
<Grid container>
<main className={styles.main}>
<h1 className={styles.title}>{t("title")}</h1>
{currentUser ? (
<Link href="/about">
<a>{t("buttons.about")}</a>
</Link>
) : (
<GoogleSignInButton onClick={signIn} />
)}
</main>
</Grid>
);
};
const HomeWrapper = () => (
<Suspense fallback={<CircularProgress />}>
<Home />
</Suspense>
);
export default HomeWrapper;
検証
この状態でフロントエンドのhttp://localhost:3000/
にアクセスする
GOOGLEでサインイン
ボタンのクリックがsignIn
メソッドに繋がってる感じ
FooterにEmulatorモードですって親切に出てる
実際に押してみるとこんなの出てくる
Auto-generateで適当な情報突っ込んでsign in with google
http://localhost:4000/
にアクセスしてみるとさっき登録したユーザー入ってる!
実際のFirebase Authenticationに入ってないので
ローカルのEmulatorだけがちゃんと動いてそうだぞー
コンテナ落として再度あげて、http://localhost:4000/
にアクセスしてみると
ちゃんと登録してユーザー残ってる!いい感じ!
docker-compose down
Stopping frontend ... done
Stopping storybook ... done
Stopping firebase ... done
Removing frontend ... done
Removing storybook ... done
Removing firebase ... done
Removing network base-app_default
docker-compose up -d
Creating network "base-app_default" with the default driver
Creating firebase ... done
Creating frontend ... done
Creating storybook ... done
まとめ
最近仕事変わってGCPからAWSメインに変わりそうな雰囲気なので
あんまり使わなくなりそう・・・AWSだとcognitoとかになるのかな...何もわからん🥸
ローカルは無邪気に触りたいのでこういう外部サービスのemulatorがあるのは助かる🏄♂️
Discussion