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のセキュリティルールを次のようにしました。
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とが一致しないデータ が含まれていたからです。
mounted () {
this.$store.dispatch('setNotesRef', db.collection('notes'));
},
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下はこんな感じです。
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");
})
},
};
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のセキュリティルール + 検索条件のコーディングをする