Firebase Emulatorで開発するまで
firebase-tools
npm i -g
でインストールしてもいいけど、グローバルにインストールしなくても npx
で firebase
コマンドを使えばいい。
$ npx -p firebase-tools -c 'firebase login'
こうするとブラウザが起動してfirebaseにログインする。
$ npx firebase-tools login
でも実行できるみたいやねんけど、どっちがいいんやろか。
firebase init
npx -p firebase-tools -c 'firebase init'
色々質問されるのでてきとーに答える。 firebase.json
ができるので中身を見てみる。
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"emulators": {
"firestore": {
"port": "8080"
},
"auth": {
"port": "9099"
}
}
}
emulators
で firestore
と auth
がある。ほかにも functions
や pubsub
もエミュレーターできる。
エミュレータの起動
$ npx -p firebase-tools -c 'firebase emulators:start --project test --import=./data/firebase --export-on-exit=./data/firebase'
rootディレクトリに ./daat/firebase
作っておけば、エミュレータで追加したデータがここに保管される。 --export-on-exit
オプションでつければ、エミュレータ終了時にexportしてくれる
http://localhost:4000/
でエミュレータの管理画面にアクセスができる。
firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /public/v1/users/{userId} {
allow read: if isAuthUser(request.auth, userId);
}
}
}
ちょっと雑ですがこんな感じのルールを作ってみます。
rulesのdeploy
$ npx -p firebase-tools -c 'firebase deploy --only firestore:rules --project プロジェクトID'
成功するとこんな感じのログが出る
i deploying firestore
i cloud.firestore: checking firestore.rules for compilation errors...
✔ cloud.firestore: rules file firestore.rules compiled successfully
i firestore: uploading rules firestore.rules...
✔ firestore: released rules firestore.rules to cloud.firestore
✔ Deploy complete!
firestore rules testing
先人の知恵をお借りする。firebaseのテストライブラリ @firebase/testing はもう非推奨みたいで、 @firebase/rules-unit-testing
が推奨みたい。 @firebase/testing
で書かれている内容でもテストコードは大きくは変わりません。
package.json
"test": "jest --detectOpenHandles ./src && npm run test:firestore",
"test:firestore": "npx -p firebase-tools -c 'firebase emulators:exec --only firestore \"jest __tests__/firestore --detectOpenHandles\"'",
jest.config
firestoreのテストコードは作業ディレクトリというよりルートディレクトリに __tests___/firestore
を作ったほうがいいような気がする。
.
├── README.md
├── __tests__
│ └── firestore
├── data
├── firebase.json
├── firestore-debug.log
├── firestore.indexes.json
├── firestore.rules
├── jest.config.js
├── next-env.d.ts
├── next.config.js
├── node_modules
├── package.json
├── public
├── src
├── tsconfig.json
└── yarn.lock
ということで、 jest.config.js
の moduleNameMapper
はこんな感じになると思います。
moduleNameMapper: {
// "src(.*)$": "<rootDir>/src/$1",
"^@/(.*)$": "<rootDir>/$1",
"\\.(css|less|sass|scss)$": "identity-obj-proxy",
"\\.(gif|ttf|eot|svg|png)$": "<rootDir>/test/__mocks__/fileMock.js",
},
Emulatorが起動しない場合
だいたい起動しない原因は、エミュレータを止める時にCtrl + C
を連打して、止めるプロセス自体も止めてしまって裏でずーっと動いてることになってる場合やと思います。連打をやめるのを心がけてます。。。
⚠ firestore: Port 8080 is not open on localhost, could not start Firestore Emulator.
⚠ firestore: To select a different host/port, specify that host/port in a firebase.json config file:
{
// ...
"emulators": {
"firestore": {
"host": "HOST",
"port": "PORT"
}
}
}
i emulators: Shutting down emulators.
こんな感じのエラーが出たら動いてるプロセスを突き止めて kill
しちゃいます。
$ lsof -i:8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 59688 user 206u IPv6 0xe8af525e1bd56c65 0t0 TCP localhost:http-alt (LISTEN)
java 59688 user 208u IPv6 0xe8af525e1bd59125 0t0 TCP localhost:61371->localhost:http-alt (ESTABLISHED)
java 59688 user 209u IPv6 0xe8af525e1bd58b05 0t0 TCP localhost:http-alt->localhost:61371 (ESTABLISHED)
javaで動いてるのでjavaもろともkillします。
$ pkill java
4000portも動いてるか見ます。
$ lsof -i:4000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 53308 user 23u IPv4 0xe8af525e17b5bf35 0t0 TCP localhost:terabase (LISTEN)
node 53308 user 26u IPv4 0xe8af525e445db555 0t0 TCP localhost:terabase->localhost:55184 (ESTABLISHED)
PIDをコピってkillします
$ kill -9 53308
これで起動しなくなったエミュレータが起動するようになると思います。