我今天开始使用Firebase并尝试创建一个示例iOS应用。 目前,我一直坚持保护我的数据。
假设我有这个演示数据。
{
"Demodata" : {
"demodata-1" : {
"id" : 1,
"uid" : 1234
}
}
}
和此规则文件
{
"rules": {
"Demodata" : {
"$uid" : {
".read" : "auth.uid == $uid"
}
}
}
}
和使用uid登录的用户:1234
我使用此代码登录。
ref.authUser(email, password: password,
withCompletionBlock: { error, authData in
completion(result: error)
})
然后我尝试使用此代码获取数据。
demoDataRef.queryOrderedByChild("id").queryEqualToValue(queryValue).observeSingleEventOfType(.Value, withBlock: { snapshot in
// do some stuff once
print(snapshot)
})
但我从未从Firebase获取数据。当我删除规则并添加“.read”:true时,父项一切正常。
我确定我错过了一些东西,但此刻我有点失落。也许有人可以指出我正确的方向。
答案 0 :(得分:4)
这里有两件事不对。其中一个很容易修复,另一个更难。
您错过了JSON数据中的某个级别。当您致电queryOrderByChild("id")
时,订单将应用于 demoDataRef
的每个子节点的“id”子属性。
要修复它,请为JSON添加用户级别:
{
"Demodata" : {
"demodata-1" : {
"user1": {
"id" : 1,
"uid" : 1234
},
"user2": {
"id" : 2,
"uid" : 2345
}
}
}
}
第二个问题是您尝试在Demodata
上执行查询,但您的用户没有Demodata
的读取权限。这意味着Firebase将立即拒绝该操作。如果你附上withCancelBlock
,就会看到拒绝。
因此,虽然用户可能能够读取特定记录(甚至每个特定记录),但他们无法查询记录列表。这是Firebase安全规则的常见误解,rules cascade和rules are not filters下的文档中对此进行了解释。
不幸的是,这意味着您通常必须选择不同的方式来构建数据。存储用户时,常见的解决方案是将每个用户存储在他们的uid下:
{
"Demodata" : {
"demodata-1" : {
"1234": {
"id" : 1,
"name" : "user1"
},
"2345": {
"id" : 2,
"name" : "user2"
}
}
}
}
现在每个用户都可以通过直接查找访问自己的个人资料:
demoDataRef.childByAppendingPath(queryValue).observeSingleEventOfType(.Value...
另见: