Java 检查Firebase数据库中是否存在特定值
我正在使用Java 检查Firebase数据库中是否存在特定值,java,android,firebase,firebase-realtime-database,Java,Android,Firebase,Firebase Realtime Database,我正在使用Firebaserealtime数据库制作一个Android应用程序。当新用户在我的应用程序上注册时,该用户的数据将保存在Firebase数据库中 用户必须提供以下详细信息才能注册: 全名 电子邮件 用户名 密码 数据库结构 每当新用户尝试注册时,我必须确保每个用户的用户名都是唯一的,因此我会检查数据库中是否存在用户输入的username 为此,我编写了以下方法: private boolean usernameExists(String username) { Datab
Firebase
realtime数据库制作一个Android应用程序。当新用户在我的应用程序上注册时,该用户的数据将保存在Firebase数据库中
用户必须提供以下详细信息才能注册:
username
为此,我编写了以下方法:
private boolean usernameExists(String username) {
DatabaseReference fdbRefer = FirebaseDatabase.getInstance().getReference("Users/"+username);
return (fdbRefer != null);
}
这个方法背后的逻辑是,如果getReference
方法找不到对指定路径的引用,它将返回null,以便我可以返回fdbRefer
是否为null
。如果fdbRefer
为null
,则表示数据库中不存在username
问题
此方法的问题是,无论输入的用户名是否存在于数据库中,它总是返回true
。这让我相信fdbRefer
永远不会null
这就引出了我的问题
问题:
当在firebase
数据库中找不到指定路径时,getReference
方法返回什么?检查用户名是否已存在于数据库中的正确方法是什么?您可以使用orderBy查询来检查用户名是否存在,而不是检查引用是否存在已经
orderByChild('username')。如果某些数据已经存在,则equalTo(username)查询将返回数据,否则它将返回null。像这样检查它
fdbRefer.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exist() {
//username exist
}
else {
//username doesn't exist
}
}
});
试试这个:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("Users");
ref.orderByChild("username").equalTo(Nick123).addValueEventListener(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
if(dataSnapshot.exist() {
//username exist
}
}
您必须使用orderbychild
和equalto
检查值是否存在。
如果您不使用orderbychild
和equalto
,那么它只会检查username
子节点是否存在并且不关心值
这个orderByChild(“username”).equalTo(Nick123)
就像是说:
WHERE username=Nick123
要检查用户是否存在,请使用以下代码:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userNameRef = rootRef.child("Users").child("Nick123");
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists()) {
//create new user
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
userNameRef.addListenerForSingleValueEvent(eventListener);
您还可以使用查询来实现如下相同的功能:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("Users").orderByChild("userName").equalTo("Nick123");
query.addValueEventListener(/* ... */);
这是另一种在整个用户
节点中循环的方法,而不仅仅是直接引用单个用户。当您使用uid
而不是用户名作为用户之间的唯一标识符时(如您现在所做的),更可能使用此选项。因此,如果您的数据库结构可能与此类似:
Firebase-root
|
--- Users
|
--- uid
|
--- userName: "Test User"
|
--- emailAddress: "user@email.com"
第二种解决方案是推荐的解决方案
还有另一个解决方案,其中包括创建另一个名为用户名的节点,在该节点中,您只能保存唯一的用户名。请参阅以下相应的安全规则:
"Users": {
"$uid": {
".write": "auth !== null && auth.uid === $uid",
".read": "auth !== null && auth.provider === 'password'",
"userName": {
".validate": "
!root.child('userNames').child(newData.val()).exists() ||
root.child('userNames').child(newData.val()).val() == $uid"
}
}
}
但是,由于在本例中,您的用户名已经是节点的名称,因此我建议您继续使用第一个名称。由于您已经找到了问题的解决方案,我将尝试解释代码不起作用的原因
您可能会认为,在上述语句中,如果数据库中不存在“Users/”+username,则fdbRefer
将为null。
但实际上,该语句只存储getReference()
中指定字段的路径。所以当你检查fdbRef=null
,它始终为真,因为fdbRefer
将保存类似以下内容的值https://.firebase.com/Users/Nick123.非常适合我
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference
.child(getString(R.string.dbname_users))
.orderByChild("username")
.equalTo(username);
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.getChildrenCount()>0) {
//username found
}else{
// username not found
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
请参见这两种方法之间的差异。使用第一种解决方案将帮助您节省带宽。您能否解释一下(!dataSnapshot.exists())
的作用是什么?dataSnapshot
对象表示以下位置的快照:Firebase root->Users->Nick123
。最好的解决方案是直接在dataSnapshot
上使用exists()
方法检查是否存在。当您使用查询时,您在整个对象中循环,这意味着浪费带宽。我还给您提供了查询解决方案,也许您将来会需要。@RedM第一个解决方案是使用直接指向特定用户的引用,而第二个解决方案是使用搜索整个对象以找到相应用户的查询。@MehulTank在这种情况下,您应该使用Peter的答案。
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference
.child(getString(R.string.dbname_users))
.orderByChild("username")
.equalTo(username);
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.getChildrenCount()>0) {
//username found
}else{
// username not found
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});