LoginSignup
49
28

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-04-14

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は書いたもののうまく動かない」、「ここの値これが入ってくるはずなのにうまく動いていない」というときに活用してみてください。

参考

49
28
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
49
28