我有一个问题,我可以在各种网站或论坛上找到信息,但是找不到适合我的解决方案。
我在firebase中具有这种实时数据库结构:
我要应用安全规则。 应用以下规则,只有经过正确身份验证的用户才能获取信息。
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
到目前为止,一切正常。从逻辑上讲,它表明任何经过身份验证的用户都可以访问任何信息
现在,我希望经过身份验证的用户只能访问其节点。
根据我发现的信息,使用以下规则应该很容易:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
但是,我总是会收到错误消息:
W / SyncTree:侦听/失败:DatabaseError:权限被拒绝
这是通过android代码建立的连接:
database.addListenerForSingleValueEvent(object :
ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val path = dataSnapshot.child(App.res.getString(R.string.word_user))
.child(prefs.user_id.toString()).child("expenses").children
for (snapshot in path) {
...
我不明白问题出在哪里。
我知道请求是针对“费用”字段的,但由于包含在“用户”字段中,我认为应该没有问题。
正如我所说,我已经阅读了很多,但是我无法使它正常工作。
预先感谢
答案 0 :(得分:1)
从错误消息看来,您好像正在将侦听器附加到数据库的根目录。尝试执行此操作时,Firebase会检查您是否具有读取根目录的权限。您的规则不授予任何人读取数据库根目录的权限,因此读取被拒绝。
重要的是要认识到规则不会过滤数据,而只是强制所有对数据的访问都遵循规则。由于您仅授予对/users/$uid
的访问权限,因此只能将侦听器附加到/users/$uid
或更低版本。
解决方案是将您现在在onDataChange
内部进行的路径构建移到外部:
database
.child(App.res.getString(R.string.word_user))
.child(prefs.user_id.toString())
.child("expenses")
.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (snapshot in dataSnapshot.children) {
...
这不仅确保您的代码被允许读取数据,而且意味着它尝试下载更少的数据(这为您和您的用户节省了金钱和时间)。
另请参阅: