我正在使用Firebase实时数据库作为Android应用的数据存储,现在我正在尝试根据用户权限实施一些基本过滤。
这是我的数据库:
{
"admins" : {
`user1hash` : true
},
"clients" : {
"client1hash" : {
"owner": "user1hash",
"name" : "Client 1"
},
"client2hash" : {
"owner": "user1hash",
"name" : "Client 2"
},
"client3hash" : {
"owner": "user2hash",
"name" : "Client 3"
}
}
}
我按照{strong>基于查询的规则部分https://firebase.google.com/docs/database/security/securing-data中的示例进行了操作,并按照以下规则定义了我的规则:
{
"rules": {
"clients": {
".indexOn": "owner",
".read": "auth.uid != null && (root.child('admins/' + auth.uid).val() == true || query.orderByChild == 'owner' && query.equalTo == auth.uid)",
".write": "auth.uid != null",
".validate": "newData.hasChildren(['owner']) && newData.child('owner').val() == auth.uid"
}
}
}
这是我的客户端代码(Android):
FirebaseDatabase database = FirebaseDatabase.getInstance();
String authUser = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference clientsDatabase = database.getReference("clients").orderByChild("owner").equalTo(authUser).getRef();
clientsDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// handle success
}
@Override
public void onCancelled(DatabaseError databaseError) {
// handle error
}
});
所以基本上我只是希望能够获取所有客户端,但是根据当前用户的访问规则过滤结果。访问规则非常简单,用户只能看到owner
所在的客户端,但可以查看所有客户端的管理员用户除外。例如,如果这是由管理员user1运行,他应该看到所有三个客户端,但如果这是由常规用户user2运行,他应该只看到客户端3。
此实现适用于管理员,但我收到普通用户的权限错误。
我在Firebase控制台中尝试过规则模拟器,但它没有提供有关如何使用查询的任何文档。无论如何,我尝试将查询添加为常规URL查询字符串,如/clients?orderByChild=owner&equalTo=user2hash
,但这会在模拟器上返回一个空错误,但不会说明原因。我在Android端遇到的错误也没有任何描述,只是一般性权限错误。
答案 0 :(得分:1)
问题出在这句话中:
DatabaseReference clientsDatabase =
database.getReference("clients")
.orderByChild("owner")
.equalTo(authUser)
.getRef();
特别是最后一行getRef()
,它会抛出您构建查询所做的一切。上述陈述使clientsDatabase
完全相同:
DatabaseReference clientsDatabase = database.getReference("clients");
这很好地解释了为什么声明失败。
你需要保留你所获得的Query
并将你的听众附上:
DatabaseReference clientsDatabase = database.getReference("clients");
Query query = clientsDatabase.orderByChild("owner").equalTo(authUser);
query.addListenerForSingleValueEvent(new ValueEventListener() { ...