我想允许访问用户名,以便其他用户可以按用户名搜索用途。
我的应用程序中具有搜索功能,该功能允许用户通过用户名搜索其他用户
Firebase规则
{
"rules": {
"users": {
"$uid": {
// Allow only authenticated content owners access to their data
".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"
}
}
}
在我的应用程序中,我具有一个允许用户更改其用户名的功能,通过此代码,我试图验证用户名是否由其他用户替换,我通常会访问单个用户信息如果仅为经过身份验证的用户配置Firebase规则,则by child(uid)
可以工作,但是为了验证用户名,我不需要对child(uid)
进行排序,因为这只会返回当前用户的单个用户,我需要按child(“ users”)。orderBy(“ userName”)进行排序,这会返回PERMISSION DENIED,因为我没有通过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("User name not available");
}else {
updateUserName(chatUserName);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
答案 0 :(得分:1)
用户要么可以访问整个节点,要么根本就不能访问该节点。无法让他们仅访问每个子节点的一部分。
但是,即使有,您的代码也会有问题:另一个用户可能会在查询运行的时间之间声明该名称,然后您将新的用户名写入数据库。虽然在您的测试中似乎不太可能出现此问题,但在成功的应用程序中,此类问题(称为竞争状况)一定会再次出现并咬住您。
实现唯一性的惯用方式(也是唯一有保证的方式)是使用必须唯一的事物作为数据库列表中的键。因此,对于您而言,这意味着:
与其在此重复,不如让我指出以前的一些问题,这些问题将在下面详细介绍: