如何允许访问需要验证uid的一个特定字段,firebase数据库规则。

7 浏览
0 Comments

如何允许访问需要验证uid的一个特定字段,firebase数据库规则。

我想允许其他用户通过用户名搜索用户,因此我在我的应用程序中有一个搜索功能,允许用户通过用户名搜索其他用户。

Firebase规则如下:

{

"rules": {

"users": {

"$uid": {

// 仅允许已验证的内容所有者访问他们的数据

".read": "auth.uid != null",

".write": "auth.uid != null"

},

},

"chat": {

"messages": {

".write": true,

".read": true

}

},

"app-settings": {

".write": true,

".read": true

}

}

}

这是用户的JSON数据:

{

"app-settings" : {

"app-Available" : true,

"version" : "4"

},

"users" : {

"uid" : {

"blocked" : false,

"email" : "gamatiaihab@gmail.com",

"profilePhotoUrl" : "https://lh3.googleusercontent.com/a-/AOh14Gi6eXrdLfZTQH0B7GvoTxhqBHoVFUUTibK3QKfrfA=s96-c",

"uid" : "uid",

"userName" : "gamatiaihab"

}

}

}

在我的应用程序中,我有一个功能允许用户更改他们的用户名。通过这段代码,我尝试验证用户名是否被其他用户所使用。通常,我使用`child(uid)`访问单个用户信息。如果Firebase规则仅针对已验证的用户配置,这将起作用。但是为了验证用户名,我需要按`child("users").orderBy("userName")`排序,而这会返回权限被拒绝,因为我没有传递`child(uid)`。

private void validateUserName(final String chatUserName){
    mEditChatUserNamePr.setVisibility(View.VISIBLE);
    mDb = FirebaseDatabase.getInstance().getReference().child("users");
    mDb.orderByChild("userName")
            .equalTo(chatUserName)
             .addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if (dataSnapshot.getValue() != null){
                mEditChatUserNamePr.setVisibility(View.GONE);
                mChatUserNameInput.setError("用户名不可用");
            }else {
                updateUserName(chatUserName);
            }
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }
    });
}

0
0 Comments

问题的原因是在Firebase数据库中,要么用户对整个节点具有访问权限,要么对节点没有任何访问权限。无法仅授予他们对每个子节点的部分访问权限。

然而,即使有这种可能性,你的代码仍然会有问题:在查询运行和将新用户名写入数据库之间的时间内,另一个用户可能会声明该用户名。虽然这个问题在测试中可能看起来不太可能发生,但在一个成功的应用程序中,这种问题(也称为竞态条件)肯定会出现。

实现唯一性的惯用(也是唯一保证的)方法是使用必须是唯一的东西作为数据库中列表中的键。所以在你的情况下,这意味着:

1. 创建一个用户名列表,其中每个键都是一个用户名,每个值都是具有该用户名的用户的UID。

2. 使用事务确保没有两个用户同时更新同一个节点。

3. 使用安全规则确保没有人可以覆盖已经被另一个用户声明的用户名。

除了在这里重复更多的内容外,让我指向一些以前的问题,其中更详细地涵盖了这个问题的解决方法:

- Firebase android : make username unique

- How do you prevent duplicate user properties in Firebase?

- unique property in Firebase

- Firebase security rules to check unique value of a child #AskFirebase

0