Firebase
firebase-tools
Firestore
CloudFirestore
SecurityRules

【便利】Cloud Firestoreのrulesで値を確認できるdebug()関数

firebase-toolsのv6.4.0から、Cloud Firestoreのrulesで使えるdebug関数が追加されました。


Introduced debug(...) function to Firestore emulator security rules


はじめはどう使うのか分からず「そういうのがあるんだなー」くらいで流していたのですが、先日使い方を知ることができたのでさくっとまとめてみます。


どういうものか

debug()関数は、firestore.rules内に記述できる関数で、この関数の引数に渡した情報を、出力してくれます。

名前の通り、debug目的で使うものとなっていて、Firestore Emulatorを起動している状態でのrulesのテスト等に活用することができます。

Emulatorを起動した状態で、該当のルールが評価されるタイミングで、debug(...)内の値がEmulatorを実行しているターミナルに出力されます。


使い方

service cloud.firestore {

match /databases/{database}/documents {
match /users/{userId} {
allow write: if debug(request.auth.uid) != null;
}
}
}

例えばこのようにrequest.auth.uidをdebug関数で包み、

const db = firebase

.initializeTestApp({
projectId: project_id,
auth: { uid: 'alice'}
})
.firestore()

として初期化したfirestoreを使ってテストを書くと、次のようにターミナル上に出力されます

string_value: "alice"


出力できる形式

出力できるものとしては、 リファレンスに記述のある型となります。

あとはnullも出力されます。

null_value: NULL_VALUE

resource を試しに出力してみるとこのようになります

map_value {

fields {
key: "data"
value {
map_value {
fields {
key: "birthday"
value {
string_value: "January 1"
}
}
}
}
}
fields {
key: "__name__"
value {
path_value {
segments {
simple: "databases"
}
segments {
simple: "(default)"
}
segments {
simple: "documents"
}
segments {
simple: "users"
}
segments {
simple: "alice"
}
}
}
}
fields {
key: "id"
value {
string_value: "alice"
}
}
}


出力されないもの

debug関数に渡したものが、undefined や評価結果としてerrorになってしまっているものに関しては出力されません。

その場合はEmulator側でログが吐き出されていたり、テストでerrorをcatchして情報を得ることができます。

FirebaseError: [code=permission-denied]:

Property xxx is undefined on object. for 'get' @ L12
at FirestoreError.Error (native)


ちょっと便利になるやつ

次のような関数を準備してあげると、requestやresourceの状態を出力しつつ、後続の条件をそのまま評価できるようになるので便利です。

service cloud.firestore {

function printRequest() {
return debug(request) || true;
}

function printResource() {
return debug(resource) || true;
}

match /databases/{database}/documents {
match /users/{userId} {
allow read: if printResource() && request.auth.uid != null;
allow write: if printRequest() && request.auth.uid != null;
}
}
}


【注意】deploy前にはdebug関数を消そう

debug関数を書いたままdeploy自体はできますが、実際に実行されるときにはdebug関数自体は未定義になり、errorが発生するので注意です。

試しにdebug関数を書いたままdeployし、webコンソールのルールシミュレーターで該当する部分の検証を行うと次のようなエラーが出ると思います。

スクリーンショット 2019-04-14 14.31.26.png


まとめ

今まではある変数に格納されている値がなんであるのか、関数を評価した結果何が帰っているか分かりづらかったのですが、debug関数の登場により原因を特定しやすくなるかと思います。

「ruleは書いたもののうまく動かない」、「ここの値これが入ってくるはずなのにうまく動いていない」というときに活用してみてください。


参考