前置き
こちらのシリーズの
Realtime Database版🌟
チャット機能(Realtime Database)と
タスク管理機能(Cloud Firestore)の
アプリを作成。
ルール設定や送信、取得のメソッドなど
見直し、整理します✨👀
⬇️ルールは少し
Cloud Firestoreと異なりますが、
違いの理解をするのに役立つと思います🍀
【Nuxt.js】Firebase Auth × Cloud Firestore ログインアカウントの送信と取得を考える
【Nuxt.js】Firebase Auth × Cloud Firestore ログインアカウントの送信と取得を考える②
おさらい: タスク管理機能
ログインユーザーかつ
送信したデータ内のuid
とauth
で取得しているuid
が
一致する場合のみ
読み書きを可能にしたい❗️
ルール変更が必要で、
取得する際にも.where
でuid
が一致するデータのみ取得して
安全性を高めていました。
1 2 3 4 5 6 7 8 9 |
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /task/{task} { allow write: if request.auth != null && request.auth.uid == request.resource.data.uid; allow read: if request.auth != null && request.auth.uid == resource.data.uid; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
export const actions = { async submitTask({ dispatch }, { task, uid }) { try { await this.$fire.firestore.collection('task').doc().set({ task, uid, }) dispatch('getData') } catch (error) { console.log(error) //eslint-disable-line } }, async getData({ commit }) { try { const user = this.$fire.auth.currentUser const querySnapshot = await this.$fire.firestore .collection('task') .where('uid', '==', user.uid) .get() const todos = [] querySnapshot.forEach((doc) => { const data = doc.data() todos.push(data) }) commit('setData', todos) } catch (error) { console.log(error) } }, } |
チャット機能のルールをチェック
ルールはCloud Firestoreと同じように
実行するかしないかの設定です。
フィルターをかけて
データを絞るものではありません。
Cloud Firestoreの取得に使用していた.where
がフィルターの役割です🍀
まずはどんなルールにしたいか
ざっくりイメージ。
チャットなので
全員のデータを見れるようにします💫
ただ書き込み、編集は
Authのuid
と送信されたuid
が一致している場合、
などに制限する方が良いですね。
自分が送ったメッセージを
他の人が編集できたら怖いので😵
デフォルトのルールとデータ構造
デフォルトのルールはこちら。
無条件に読み書きできます。
1 2 3 4 5 6 |
{ "rules": { ".read": true, ".write": true } } |
RDBのデータ構想はこんな感じですね。
Cloud Firestoreのような
コレクションはありません。
ルールを理解する
ではこちらから確認していきます。
Authorization$
でワイルドカードとして使用可能。
つまりusers
以降の階層すべてで
送信しているuid
とFirebaseAuthのuid
が
一致していれば書き込みできる
ということです。
$ 変数を使用してパス セグメントをキャプチャする
1 2 3 4 5 6 7 8 9 10 |
{ "rules": { "users": { "$uid": { ".read": "$uid === auth.uid", ".write": "$uid === auth.uid", } } } } |
コード
送信はusers内のキーをuid
に。ref
に階層名のusers
そしてuid
とすればOKです。
ただset()だと1つのデータを作成して
上書きしかできないので、変更は必要。
チャットなので複数のデータが必要です。
とりあえずルールに沿うと、こう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
export const actions = { async submitChat(_, payload) { try { await this.$fire.database.ref('users/' + payload.uid).set({ text: payload.text, time: this.$fireModule.database.ServerValue.TIMESTAMP, uid: payload.uid, }) } catch (error) { console.log(error)//eslint-disable-line } }, } |
TvPlyergs…
これがFirebaseAuthで
ログインしているuid
です。
では複数のデータを扱うためにはどうするか。
push()で一意のキーを生成(自動生成)❗️
ということで、ref
の後ろに追加してみましょう✍️
1 2 3 4 5 6 7 8 9 10 11 12 13 |
export const actions = { async submitChat(_, payload) { try { await this.$fire.database.ref('users/' + payload.uid).push().set({ text: payload.text, time: this.$fireModule.database.ServerValue.TIMESTAMP, uid: payload.uid, }) } catch (error) { console.log(error)//eslint-disable-line } }, } |
users/uid/自動生成されたkey
これで複数のデータを保管できます✨🙌
ちなみにCloud Firestoreでは
書き込みの際、
これから送信するデータのuid
を
認識させるためにrequest
が必要でした(★)
1 2 3 4 5 6 7 8 9 |
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /task/{task} { allow write: if request.auth != null && request.auth.uid == ★request.resource.data.uid; allow read: if request.auth != null && request.auth.uid == resource.data.uid; } } } |
現段階では必要なさそうです。
使うとしたらこちらが考えられます💡
request.auth
まとめ
Cloud Firestoreではread
の設定を先にやっていて、
あとからwrite
でエラーが起きたので、
今回はwrite
からスムーズにできるよう
チェックしています🍀
write
が終わってから、
表示させるために
取得のデータの形を変更する必要も
出てくるかもしれないので、
そちらもやっていきます🌟