LoginSignup
0
0

More than 3 years have passed since last update.

FirebaseのセキュリティルールをWHEREのように使えると思っていた

Last updated at Posted at 2020-05-21

Nuxt.js+Firebaseの勉強を始めたばかりです。
みなさんの記事を見よう見まねで、WebページでFirestoreのデータベースにデータを登録できるところまで作成しました。

前回: Nuxt.js+Firebaseでログイン情報を保持したい

やりたいこと

Firestoreのデータを誰でも閲覧できてしまっては困るので、ログインユーザーごとにデータを出し分けたいと思います。

環境

  • Firebase 7.3.0
  • Vue CLI 4.0.5
  • Nuxt.js 2.10.2

セキュリティルールを変更したが...

Firestoreの構成は次の通りです。

コレクション ドキュメント フィールド
notes (uid) ・content

ログインユーザーのuidとドキュメントのuidとが一致するデータを画面に表示したかったので、Firestoreのセキュリティルールを次のようにしました。

firestore.rules
service cloud.firestore {
  match /databases/{database}/documents {
    match /notes/{userId} {
      function isOwner() {   
        return request.auth.uid == userId;
      }

      allow update, delete: if isOwner();
      allow create: if request.auth.uid != null;
      allow read: if isOwner();
    }
  }
}

Webページを開いてみたら取得結果が0件になっていました。ログインユーザーが登録したデータも表示されません。

セキュリティルールはフィルターではない

FirestoreのセキュリティルールをWHEREのように使えると思っていました。
取得結果が0件になったのは、Firestoreの検索結果に ログインユーザーのuidとドキュメントのuidとが一致しないデータ が含まれていたからです。

修正前のpages/index.vue
  mounted () {
    this.$store.dispatch('setNotesRef', db.collection('notes'));
  },
修正後のpages/index.vue
  mounted () {
    let userID = this.$store.getters['auth/getUid'];
    this.$store.dispatch('setNotesRef', db.collection('notes').doc(userID));
  },

db.collection('notes').doc(userID) には ログインユーザーのuidとドキュメントのuidとが一致しないデータ は含まれていない、つまりルールに一致するデータのみなので、Firestoreからログインユーザーのデータだけを取り出すことができました。

参考までに~/store下はこんな感じです。

store/auth.js
import Vue from 'vue';
import { auth } from '~/plugins/firebase';

export const state = () => ({
        user: {},
        status: ""
    });

export const mutations = {
        setUser(state, user) {
            state.status = "loggedIn";
            state.user = user;
        },
        logout(state) {
            state.status = "loggedOut";
            state.user = {};
        }
    };

export const getters = {
        isLoggedIn: (state) => {
          return state.status === "loggedIn";
        },
        getUsername: (state) => state.user.displayName,
        getUid: (state) => state.user.uid
    };

export const actions = {
        gotUser({ commit }, user) {
            commit("setUser", user);
        },
        logout({ commit }) {
            auth.signOut().then(() => {
                commit("logout");
            })
        },
    };
store/index.js
import { vuexfireMutations, firestoreAction } from 'vuexfire';
import createPersistedState from "vuex-persistedstate";

export const state = () => ({
      notes: [],
    });

export const mutations = {
      ...vuexfireMutations
    };

export const getters = {
      getNotes: (state) => {
        return state.notes;
      },
    };

export const actions = {
      nuxtClientInit ({ commit, state, dispatch }, { req }) {
        createPersistedState()(this);
      },
      setNotesRef: firestoreAction(({ bindFirestoreRef }, ref) => {
        bindFirestoreRef('notes', ref);
      }),
    };

まとめ

今回学んだことのまとめです。

  • Firestoreのセキュリティルールはフィルターではない
  • Firestoreのセキュリティルール + 検索条件のコーディングをする
0
0
0

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
0
0