LoginSignup
60
50

More than 3 years have passed since last update.

Firebase Firestoreのcollection groupを使ってみる

Last updated at Posted at 2019-05-19

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 > インデックス > 複合
このモーダルのコンテンツがスクロールできることに気づかなくて数分使った :cry:
Screen Shot 2019-05-19 at 10.30.04.png

isPublic, timestampでインデックスを作成した
Screen Shot 2019-05-19 at 10.33.10.png

取得

以下のように取得した

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が含まれてるとエラーになる :thinking:
    • FirebaseError: Missing or insufficient permissions.
  • 日本語だとcollection groupのドキュメントのページが(現状)無い
    • 日本語が追加されてた
  • isPublicでフィルタしたいだけなら、単一フィールドで除外を追加すると良さそう
60
50
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
60
50