security rulesとindexesも含めたら思ったより時間がかかってしまったのでメモ
やりたいこと
メッセージの公開/非公開を設定できるメッセージ投稿アプリを考える
公開されたメッセージの一覧を表示したい
Firestoreの構造は以下のようにする
user/{uid}/posts/{docId}
{
body: string,
timestamp: timestamp,
isPublic: boolean
}
posts以下の、isPublic: true
なdoc一覧を取得したい
やったこと
security rules
security rulesは以下のようにした
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function published() {
return resource.data.isPublic == true
}
match /user/{uid} {
match /posts/{docId} {
allow read, write: if request.auth.uid == uid;
}
}
match /{path=**}/posts/{docId} {
allow list: if published();
allow get: if published();
}
}
}
Firebaseのdocumentを参考にした
一行目の rules_version = '2';
と、
最後のmatch /{path=**}/posts/{docId}
が必要っぽい
indexes
公開メッセージを時間順に並べたいので、インデックスを設定する
Firebaseのconsoleでインデックスを設定する
Database > インデックス > 複合
このモーダルのコンテンツがスクロールできることに気づかなくて数分使った
isPublic, timestampでインデックスを作成した
取得
以下のように取得した
const firestore = firebase.firestore()
const snapshot = await firestore
.collectionGroup("posts")
.where('isPublic', '==', true)
.orderBy('timestamp', 'desc')
.get()
snapshot.forEach(function(doc) {
console.log(doc.id, doc.data())
}
無事取得できた
わかったこと
- collection idが同じならどの階層にあってもそれ以下のdocsを取得する
- 一つでもlist, get権限がないcollectionが含まれてるとエラーになる
FirebaseError: Missing or insufficient permissions.
-
日本語だとcollection groupのドキュメントのページが(現状)無い- 日本語が追加されてた
- isPublicでフィルタしたいだけなら、単一フィールドで除外を追加すると良さそう