根据身份验证过滤Firebase实时数据库数据

时间:2018-04-07 18:44:32

标签: android firebase firebase-realtime-database firebase-authentication firebase-security-rules

我正在使用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端遇到的错误也没有任何描述,只是一般性权限错误。

1 个答案:

答案 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() { ...
相关问题