firebase JavaScript SDK v5.3.0以降で、Firestoreでのarray(list)の扱いが劇的に向上し、

  • where句での検索(array-contains の使用)
  • 要素の追加削除の向上(array union/remove)

が提供された。これに伴って、Firestoreのrulesでも、read時にarray-containsのクエリのチェックができるようになったので試してみた。

rulesを書く

例えば、client側からは、以下のようなクエリでgroupドキュメントを取得することを想定する

const authUserID = ...
const groups = await firestore.collection('groups')
  .where('users', 'array-contains', authUserID)
  .get()

これに対応するrulesを書くと次のようになる。

service cloud.firestore {
  match /databases/{database}/documents {
    match /groups/{groupID} {
      allow list: if request.auth.uid in resource.data.users;
    }
  }
}

resource.data.users でusersフィールドを参照し、その中にauthUserIDが含まれているかをin演算子で確認している。これで、array-containsのwhere句に対応できる。

さくっと動作を試したい

ルールシミュレータを使うとさっと確認できる。
まずは、次のようにgroupsコレクション以下にドキュメントを作る。
(documentIDとusers内のIDはわかりやすいものにしている)

その後、ルールを書き換え、シミュレータにて以下の条件でシミュレートする

  • オペレーション: list
  • path: /groups/{groupドキュメントのID}
  • 認証情報: ありでuidgroup.users内にあるIDと同じにする

🎉

参考