Nuxt + Firebase FirebaseError: Missing or insufficient permissions

Nuxt + Firebase FirebaseError: Missing or insufficient permissions

仅当文档具有使用 firebase 登录的当前用户的用户 ID 时,我才尝试读取文档集合。这是我的数据库规则:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {  
    match /todos/{todoId} {
      allow read: if isLoggedIn() && request.auth.uid == resource.data.userId;
      allow create: if isLoggedIn() && request.auth.uid == request.resource.data.userId;
      allow update, delete: if isLoggedIn() && request.auth.uid == resource.data.userId;
    }
    
    function isLoggedIn() {
        return request.auth != null;
    }
  }
}

创建文档不是问题,阅读文档才是问题。这是我检索数据的函数:

getData () {
  this.$fire.firestore.collection('todos').get()
    .then((doc) => {
      if (doc.exists) {
        console.log('Document data:', doc.data())
      } else {
        // doc.data() will be undefined in this case
        console.log('No such document!')
      }
    }).catch((error) => {
      console.log('Error getting document:', error)
    })
}

似乎 resource.data.id 规则未指向待办事项用户 ID,因此我得到 FirebaseError:权限缺失或不足。这是我当前的数据库结构:

关于为什么规则没有按预期工作有什么想法吗?

我已经解决了问题,从firestore获取数据的方法不完整,the solution was in the firebase documentation

正确的数据检索方法是使用 where 约束:

getData () {
      this.$fire.firestore.collection('todos').where('userId', '==', this.user.uid).get()
        .then((docs) => {
          if (docs) {
            // console.log('Document data:', docs.data())
            docs.forEach((doc) => {
              console.log(doc.data())
            })
          } else {
            // doc.data() will be undefined in this case
            console.log('No such document!')
          }
        }).catch((error) => {
          console.log('Error getting document:', error)
        })
    }

Firebase security rules don't filter data。相反,他们只是确保您执行的任何操作符合您设置的规则。

所以你的这条规则说用户只能阅读有自己的 UID 的文档:

allow read: if isLoggedIn() && request.auth.uid == resource.data.userId;

但是您的代码会继续并尝试读取所有文档:

this.$fire.firestore.collection('todos').get()

由于您的规则不允许读取所有文档,因此操作被拒绝。

要允许该操作,请确保您的读取操作符合您的规则并且仅请求 UID 匹配的文档:

let uid = ...
this.$fire.firestore.collection('todos').where("userId", "==", uid).get()