在/ items上获得permission_denied:客户端没有访问所需数据的权限

时间:2019-05-06 17:28:11

标签: javascript firebase firebase-realtime-database firebase-security-rules

我正在定义一个Firebase规则以通过userId读取数据。 userId是用户创建的每个数据上的标志,它当然是用户uid。

她的规则如下:

{
    "rules": {
      "items": {
        "$itemId": {
         ".read": "auth !== null && root.child('items/$itemId/userId').val() === auth.uid"
        }
      }
    }
}

我正在这样访问客户端数据:

firebase.database().ref(`/items`)
    .once('value')
    .then(snapshot => {
      const places = []
      const data = snapshot.val();
      for (let key in data) {
        places.push({
          ...data[key],
          key: key
        });
      }
    })

我希望根据每个项目上的userId标志对所有者进行数据访问。

以下数据结构的示例:

1 个答案:

答案 0 :(得分:1)

根据Firebase文档rules are not filters。但是,去年(2018年)引入了查询规则,我认为blog postdocs更好。

因此,要保留当前数据结构,您的规则应更改为:

{
    "rules": {
      "items": {
         ".read": "query.orderByChild == 'userId' && query.equalTo == auth.uid"
      }
    }
}

然后,您还必须更改查询:

firebase.database().ref(`/items`).orderByChild('userId').equalsTo(userId)...

最后一件事,看来您的数据库结构可能指向其他需求:

  • 如果您只想让创建它的用户访问您的数据,并且要拥有一个可以查看所有内容的管理员,那么更好的解决方案是对数据进行非规范化。您的数据结构为:
user_items: {
    uid1: {
          key1:{//full object here}
     }
},
items: {
    key1:{//partial item here, just name and photo, think on a list}
},
admins:{
    uid1:true
}

这里的管理问题是通过管理节点解决的,可以与custom claimsFirebase Functions结合使用。

  • 由于有一个 places word ,也许您需要使用其他类似geofire的位置