Checking if a particular value exists in the fireb

2019-01-01 11:44发布

问题:

I am making an android application using Firebase database. When a new user registers on my app, that user\'s data is saved in firebase database.

User has to provide following details to register

1. Full Name
2. Email 
3. Username
4. Password

Database Structure

\"enter

Whenever a new user tries to register, i have to make sure that each user\'s username is unique so i have to check the database if the username entered by the user already exists in the database or not.

To do this, i wrote following method

private boolean usernameExists(String username) {
     DatabaseReference fdbRefer = FirebaseDatabase.getInstance().getReference(\"Users/\"+username);
     return (fdbRefer != null);
}

My logic behind this method is that if getReference method cannot find reference to the specified path, it will return null, so then i can return whether fdbRefer is null or not. If fdbRefer is null, then it means that username doesn\'t exists in the database.

Problem

Problem with this method is that it always returns true whether the entered username exists in the database or not. Which led me to believe that fdbRefer is never null.

This brings me to my question...

Question

What does getReference method returns when it can\'t find the specified path in the firebase database and what\'s the correct way check if the username already exists in the database or not?

回答1:

To check a existence of user, please use the below code:

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);

You can also use a Query to achieve the same thing like this:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child(\"Users\").orderByChild(\"userName\").equalTo(\"Nick123\");
query.addValueEventListener(/* ... */);

This is another approach which is looping through the entire Users node but is not just using a direct reference to a single user. This option is more likely to be used when you are using as a unique identifier beteeen users the uid instead of the user name (as you do right now). So if your database structure might looks similar to this:

Firebase-root
   |
   --- Users
        |
        --- uid
             |
             --- userName: \"Test User\"
             |
             --- emailAddress: \"user@email.com\"

The second solution is the recommended one.

There is also another solution which involves youto create another node named userNames, in which you can hold only the unique user names. Please also find below the corresponding security rules:

\"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\"
    }
  }
}

But since in this case, your user name is already the name of the node, I recommend you go ahead with the first one.



回答2:

Check it like this...

    fdbRefer.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exist() {
//username exist
}
else {
//username doesn\'t exist
}
}
});


回答3:

Try this:

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
          }
        }

You have to use orderbychild and equalto to check the value if it is there. If you dont use orderbychild and equalto then it will just check if username child node is there and doesnt care about the value.

this orderByChild(\"username\").equalTo(Nick123) is like saying:

WHERE username=Nick123


回答4:

Instead of checking for the exists of the reference you can use orderBy query to check whether username exists already

orderByChild(\'username\').equalTo(username) query would return data if some data already exists else it will return null.