Firebase 如何允许用户查询集合,但只能访问集合中的某些结果?
第一次在firebase工作并建立复杂的(对我来说)规则 我有一组孩子,他们的财产是“parentId”。我只希望某些角色和用户阅读此表。具体来说,我希望任何教练或裁判角色都能像任何孩子的父母一样阅读 我认为问题在于集合级别的“data.child('parentId').val()==auth.uid”。read。我觉得我完全遵循了这个例子,但它仍然不起作用: 有人能指出我在安全规则中做错了什么吗 我知道安全规则不会过滤,我不认为这是该特定问题的一个例子,因为我的查询专门将结果限制在我试图通过安全规则允许的范围内(尽管我可能弄错了) 以下是当前的安全规则。这些评论应该解释我的目的:Firebase 如何允许用户查询集合,但只能访问集合中的某些结果?,firebase,firebase-security,Firebase,Firebase Security,第一次在firebase工作并建立复杂的(对我来说)规则 我有一组孩子,他们的财产是“parentId”。我只希望某些角色和用户阅读此表。具体来说,我希望任何教练或裁判角色都能像任何孩子的父母一样阅读 我认为问题在于集合级别的“data.child('parentId').val()==auth.uid”。read。我觉得我完全遵循了这个例子,但它仍然不起作用: 有人能指出我在安全规则中做错了什么吗 我知道安全规则不会过滤,我不认为这是该特定问题的一个例子,因为我的查询专门将结果限制在我试图通过
"children": {
// give ability of any coach or referee to read any child. Give refs ability to write to any child. Allow parent to query for their own children.
".read": "(data.child('parentId').val() === auth.uid) ||(root.child('users').child(auth.uid).child('role').val() === 'coach') || (root.child('users').child(auth.uid).child('role').val() === 'referee')",
".write": "root.child('users').child(auth.uid).child('role').val() === 'referee'",
".indexOn": ["parentId", "isApproved"],
"$child": {
// give a parent read and write access to only their specific children.
".read": "root.child('children').child($child).child('parentId').val() === auth.uid",
".write": "root.child('children').child($child).child('parentId').val() === auth.uid"
}
}
在我的代码中,我按父ID查询所有子项。下面是我的javascript,失败的原因是“错误:权限被拒绝:客户端没有访问所需数据的权限。”:
这些评论应该能解释我的意图。问题是用户不能通过父id(等于auth.uid)查询子项。
他们可以通过以下方式查询一个:
factory.getChildById = function(id){
return new Promise(function(resolve, reject){
childrenRef.orderByKey().equalTo(id)
.once('value', function(childResult){
var childObjects = childResult.val();
processChildren(childObjects);
var child = Utilities.getFirst(childObjects);
resolve(child);
},
function(err){
if(err){
reject(err);
}
})
})
}
我已经尝试过使用模拟器,但我无法理解.orderByChild('parentId').equalTo(parentId)和Chrome开发工具网络的语法,当我触发此命令时,不会显示任何活动…您可能想再次阅读本节 规则是以原子的方式应用的。这意味着,如果该位置或父位置没有授予访问权限的规则,则读或写操作将立即失败。即使每个子路径都可以访问,在父位置的读取也将完全失败。考虑这个结构: 如果不理解规则是以原子方式计算的,那么获取/records/path可能会返回rec1而不是rec2。然而,实际结果是一个错误: 由于/records/处的读取操作是原子操作,并且没有授予对/records/下所有数据的访问权限的读取规则,因此这将引发
权限被拒绝错误。如果我们在应用程序仪表板的安全模拟器中评估此规则,我们可以看到读取操作被拒绝:
操作被拒绝,因为没有读取规则允许访问/records/path,但请注意,从未计算rec1的规则,因为它不在我们请求的路径中。要获取rec1,我们需要直接访问它:
换句话说:只有在对某个位置具有读取权限时,才能对该位置执行查询
关于同样的问题:
感谢您的详细回复,弗兰克。在上面的示例中,如果查询只是专门查找符合安全规则的记录,该怎么办?要修改您的示例:{“规则”:{“记录”:{.read”:“data.child('read').val()==true“}}}}}}}和类似这样的查询:ref.child('records').orderByChild('read').equalTo(true))这与我正在做的是等效的。如我在问题中所述,我不相信我正在使用安全规则进行过滤。
factory.getChildById = function(id){
return new Promise(function(resolve, reject){
childrenRef.orderByKey().equalTo(id)
.once('value', function(childResult){
var childObjects = childResult.val();
processChildren(childObjects);
var child = Utilities.getFirst(childObjects);
resolve(child);
},
function(err){
if(err){
reject(err);
}
})
})
}
{
"rules": {
"records": {
"rec1": {
".read": true
},
"rec2": {
".read": false
}
}
}
}
ref.child("records").once("value", function(snap) {
// success method is not called
}, function(err) {
// error callback triggered with PERMISSION_DENIED
});
Attempt to read /records with auth=Success(null)
/
/records
No .read rule allowed the operation.
Read was denied.
ref.child("records/rec1").once("value", function(snap) {
// SUCCESS!
}, function(err) {
// error callback is not called
});