如何允许访问需要验证uid的一个特定字段,firebase数据库规则。
如何允许访问需要验证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) { } }); }
问题的原因是在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