volpe’s diary

フリーランスじゃなくなったプログラマ volpe が日々便利だなぁと感じたことを中心に綴るブログです

Nuxt.js + Firebase で vuexfire を使って Cloud Firestore と連携する(データバインド・階層データ編)

データ間に親子関係がある場合は、子データに親のIDを持たせる方法と、親データのサブコレクションとして子データを持たせる階層データの方法があり得る。

ここでは、後者の階層データをバインドする方法について述べる。

以下のような階層を想定とする。

projects
└── stages

vuexfire 用いたバインドメソッド bindFirestoreRef の ref には、 projects.doc(payload.projectId).collection('stages') のように projects のドキュメントを id で指定してさらにそのサブコレクション stages を指定する。 これによって、特定の projects に紐づいた stages のデータのみバインドできる。

store/stages.js

import { firestoreAction } from 'vuexfire'
import firebase from '@/plugins/firebase'

const db = firebase.firestore()
const projects = db.collection('projects')
let stages = null

      :

export const actions = {
  initStore: firestoreAction(({ bindFirestoreRef }, payload) => {
    stages = projects.doc(payload.projectId).collection('stages')
    bindFirestoreRef('stages', stages)
  }),

ちなみに、 stagesinitStore の外で宣言しているのは別の actions (初期値設定、追加、削除等)でも使用するため。

Firestore のセキュリティルールは以下のようにしている。

service cloud.firestore {
  match /databases/{database}/documents {
    match /projects/{projectId} {
      allow read: if resource.data.userId == request.auth.uid;
      allow write: if request.auth.uid != null;
      
      match /stages/{stage} {
        allow read, write: if request.auth.uid != null;
      }      
    }
  }
}

projects はログインユーザの uid に紐づいたデータのみ参照可能としている。 階層データの stages についてはとりあえずログイン済みユーザでのアクセスを許可しているが、正直どう設定していいのかまだよくわかっていない。。