简体   繁体   中英

How to check if the particular username exists in the firebase? (Java Android)

I have tried all of the StackOverflow methods but all the methods are checking if it's null or not. I wanted to check the particular strings under the "Users" node. example: (aaaaa) (bbbbb) or the child value in it (username: "aaaaa") if users enter username as "asaaa" or "bbbbb" in registration will be a prompt error. (i want to check all of the values in all of the nodes of firebase) I have searched all over the stack overflow but most of the solutions need to know the node names in order to run. I want to retrieve all of the names of the nodes under "Users" back to check. if a user uses "aaaaa" as a username during registration will be setError in the TextInputLayout.

public class RegisterActivity extends AppCompatActivity {

EditText username, fullname, email, password;
Button register;
TextView txt_login;
public String strUsername;

FirebaseAuth auth;
DatabaseReference reference;
ProgressDialog pd;
private static final String TAG = "RegisterActivity";

private static String users_from_database;
private ArrayList<String> username_list = new ArrayList<>();


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_register);

    username = findViewById(R.id.username);
    fullname = findViewById(R.id.fullname);
    email = findViewById(R.id.email);
    password = findViewById(R.id.password);
    register = findViewById(R.id.btn_Register);
    txt_login = findViewById(R.id.txt_login);


    auth = FirebaseAuth.getInstance();

    checkForUsername();

   txt_login.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(RegisterActivity.this,HomeActivity.class));
        }
    });

    register.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            pd = new ProgressDialog(RegisterActivity.this);
            pd.setMessage("Please wait...");
            pd.show();

            String str_username = username.getText().toString();
            String str_fullname = fullname.getText().toString();
            String str_email = email.getText().toString();
            String str_password = password.getText().toString();

            strUsername = username.getText().toString().trim();

            if (!username_list.contains(strUsername)) {
                // do your job here , suppose send verification code to phone number
                if(TextUtils.isEmpty(str_username) || TextUtils.isEmpty(str_fullname) || TextUtils.isEmpty(str_email) ||
                        TextUtils.isEmpty(str_password)){
                    Toast.makeText(RegisterActivity.this,"All fields are required!",Toast.LENGTH_SHORT).show();
                    pd.dismiss();
                } else if (str_password.length() < 6) {
                    Toast.makeText(RegisterActivity.this,"Password must be over 6 characters.",Toast.LENGTH_SHORT).show();
                    pd.dismiss();
                } else {
                    register(str_username,str_fullname,str_email,str_password);
                }
            } else {
                username.setError("Username Exist");
            }



        }
    });
}
private void checkForUsername(){

    DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users/");
    ref.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            for (DataSnapshot ds : snapshot.getChildren()) {

                users_from_database = (String) ds.child("username").getValue();

                username_list.add(users_from_database);
                StringBuilder stringBuilder = new StringBuilder();
                for (String s : username_list) {
                    stringBuilder.append(s + "\n");
                }
                Log.d("ZI", stringBuilder.toString());

            }

        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            Log.d("ZI", "Failed");
        }
    });
}

private void register(final String username, final String fullname, String email, String password){
    auth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(RegisterActivity.this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()){
                        FirebaseUser firebaseUser = auth.getCurrentUser();
                        String userID = firebaseUser.getUid();

                        firebaseUser.sendEmailVerification().addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                Toast.makeText(RegisterActivity.this,"Verification Email Has Been Sent.", Toast.LENGTH_SHORT).show();
                            }
                        }).addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Log.d(TAG, "onFailure: Email not sent" + e.getMessage());
                            }
                        });


          

                        reference = FirebaseDatabase.getInstance().getReference().child("Users").child(username);

                        HashMap<String, Object> hashMap = new HashMap<>();
                        hashMap.put("username",username.toLowerCase());
                        hashMap.put("fullname",fullname);
                        hashMap.put("email",email);
                        hashMap.put("password",password);
                        hashMap.put("imageurl","");

                        reference.setValue(hashMap).addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                if(task.isSuccessful()){
                                    pd.dismiss();
                                    Intent intent = new Intent(RegisterActivity.this,EmailActivity.class);
                                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(intent);
                                }
                            }
                        });
                    } else {
                        pd.dismiss();
                        Toast.makeText(RegisterActivity.this,"Register Failed",Toast.LENGTH_SHORT).show();
                    }
                }
            });
}

}

pic 2

You can create a public path usernames where you just store the usernames that are already used and are publicly visible. When registering a new user you can check there is a username already exists. Also don't try to get all of then to check if a single one exists. Just call the path usernames/{username} and if that is null there username doens't exist. Reading all of them would blow up your Firebase bill.

Yes you can do it by following steps.

  1. get all username child from your DatabaseReference and add it to a ArrayList.

  2. Check user provided username is available in ArrayList ( from step 1 ) or not. If contains then set error, otherwise do your job to complete registration.

Update- I think you are performing button click for registration before executing / finished checkForUsername(); method. So the if...else statement not working properly and its overriding data. It was my mistake. We should perform check all users from database first then perform the next part of registration. So without using checkForUsername() method separately in onCreate() , we will do everything in button on click. check the code -

       register.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            pd = new ProgressDialog(LoginActivity.this);
            pd.setMessage("Please wait...");
            pd.show();

            String str_username = username.getText().toString();
            String str_fullname = fullname.getText().toString();
            String str_email = email.getText().toString();
            String str_password = password.getText().toString();

            strUsername = username.getText().toString().trim();


            DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users/");
            ref.addListenerForSingleValueEvent(new ValueEventListener() {
          @Override
           public void onDataChange(@NonNull DataSnapshot snapshot) {
            for (DataSnapshot ds : snapshot.getChildren()) {

                users_from_database = (String) ds.child("username").getValue();

                username_list.add(users_from_database);
                StringBuilder stringBuilder = new StringBuilder();
                for (String s : username_list) {
                    stringBuilder.append(s + "\n");
                }
              //  Log.d("ZI", stringBuilder.toString());

                  if (!username_list.contains(strUsername)) {
                    // do your job here , suppose send verification code to phone number
                    if (TextUtils.isEmpty(str_username) || TextUtils.isEmpty(str_fullname) || TextUtils.isEmpty(str_email) ||
                            TextUtils.isEmpty(str_password)) {
                        Toast.makeText(LoginActivity.this, "All fields are required!", Toast.LENGTH_SHORT).show();
                        pd.dismiss();
                    } else if (str_password.length() < 6) {
                        Toast.makeText(LoginActivity.this, "Password must be over 6 characters.", Toast.LENGTH_SHORT).show();
                        pd.dismiss();
                    } else {
                        register(str_username, str_fullname, str_email, str_password);
                    }
                } else {
                    username.setError("Username Exist");
                    pd.dismiss();
                }

            }

        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            Log.d("ZI", "Failed");
        }
    });

        }
    });

Update- you can check DataSnapshot exist or not. If not exist, then you can set test value to start your database. This will execute only one time. You may check -

       register.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            pd = new ProgressDialog(LoginActivity.this);
            pd.setMessage("Please wait...");
            pd.show();

            String str_username = username.getText().toString();
            String str_fullname = fullname.getText().toString();
            String str_email = email.getText().toString();
            String str_password = password.getText().toString();

            strUsername = username.getText().toString().trim();


            DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users/");
            ref.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {

                    if (!snapshot.exists()) {
                        HashMap<String, Object> testHash = new HashMap<>();
                        testHash.put("username", "testusername");
                        ref.child("test")
                                .setValue(testHash).addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                if (task.isSuccessful()) {
                                    ref.keepSynced(true);
                                    Toast.makeText(LoginActivity.this, "Please try again", Toast.LENGTH_SHORT).show();
                                    pd.dismiss();
                                } else {
                                    Log.d("ZI", "Failed ", task.getException());
                                }
                            }
                        });
                    } else {

                        for (DataSnapshot ds : snapshot.getChildren()) {
                            users_from_database = (String) ds.child("username").getValue();
                            username_list.add(users_from_database);
                            StringBuilder stringBuilder = new StringBuilder();
                            for (String s : username_list) {
                                stringBuilder.append(s + "\n");
                            }
                            Log.d("ZI", stringBuilder.toString());

                            if (!username_list.contains(strUsername)) {
                                // do your job here , suppose send verification code to phone number
                                if (TextUtils.isEmpty(str_username) || TextUtils.isEmpty(str_fullname) || TextUtils.isEmpty(str_email) ||
                                        TextUtils.isEmpty(str_password)) {
                                    Toast.makeText(LoginActivity.this, "All fields are required!", Toast.LENGTH_SHORT).show();
                                    pd.dismiss();
                                } else if (str_password.length() < 6) {
                                    Toast.makeText(LoginActivity.this, "Password must be over 6 characters.", Toast.LENGTH_SHORT).show();
                                    pd.dismiss();
                                } else {
                                    register(str_username, str_fullname, str_email, str_password);
                                }
                            } else {
                                username.setError("Username Exist");
                                pd.dismiss();
                            }

                        }
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {
                    Log.d("ZI", "Failed");
                }
            });

        }
    });

I have searched all over the stack overflow but most of the solutions need to know the node names in order to run.

Even in your example, you can check if a user exists by checking the existence of the following node in the database:

root/users/$userName

In code should look like this:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("Users");
DatabaseReference userNameRef = usersRef.child("aaaaa");
userNameRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (task.isSuccessful()) {
            DataSnapshot snapshot = task.getResult();
            if(snapshot.exists()) {
                String fullName = snapshot.child("fullName").getValue(String.class);
                Log.d("TAG", fullName);
            } else {
                Log.d("TAG", "The user doesn't exist!");
            }
        } else {
            Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
        }
    }
});

While @TarikHuber answer it will work, please note that in this case, it's not necessary to create an additional node to hold all usernames, since your database structure already does that. So in terms of checking if a user exists:

root/users/$userName

It's the exact same thing as:

root/usernames/$userName

Since the nodes in the Realtime Database are represented by pairs of keys and values, please note that the keys are unique. So there is no way you can have duplicate nodes. As each node can be considered a Map.

However, if by chance you can have multiple users in the database sharing the same user name, then you should use a query as in the following lines of code:

Query queryByUserName = usersRef.orderByChild("username").equalTo("aaaaa");
queryByUserName.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (task.isSuccessful()) {
            for (DataSnapshot ds : task.getResult().getChildren()) {
                if(ds.exists()) {
                    String fullName = ds.child("fullName").getValue(String.class);
                    Log.d("TAG", fullName);
                } else {
                    Log.d("TAG", "The user doesn't exist!");
                }
            }
        } else {
            Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
        }
    }
});

According to your screenshot, in both cases, the result in the logcat will be:

james

PS While @ZahidIslam answer might also work, downloading the entire "Users" node and performing the check on the client is not the best option, as it's considered very costly. It's a waste of bandwidth and resources.

Edit:

According to you last comment:

I think u misunderstood me. I want to search thru all the nodes under the rootNodes

There is no way you can create a Query that can search under all nodes inside your database. You can, however, download the entire database and do the filtering on the client, but this is very costly and not recommended.

The best option that you have is to create a separate query for each and every node, but only if all the children have the same fields. Or you can keep the users only in the "Users" node (as you do right now), and the code in my answer will always work perfectly fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM