How to avoid duplicate data in firebase Realtime database

Viewed 1689

I am currently developing an Android application which I am using firebase (Realtime feature ) as a backend service. In addition, I have developed this function as it showing down below.

 private void checkUserExisting (){
    Dataa = mRef.getReference().child("Users");
    Dataa.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (!dataSnapshot.exists()){
                CreateUserProfile();
            }else {
                final String Uname = name.getText().toString().trim();
                final String Email = emailAddress.getText().toString().trim();
                Iterator<DataSnapshot> dataSnapshots = dataSnapshot.getChildren().iterator();
                while (dataSnapshots.hasNext())
                {
                    DataSnapshot dataSnapshotChild = dataSnapshots.next();
                    String EmailAddress = dataSnapshotChild.child("Email").toString();
                    String UserName = dataSnapshotChild.child("UserName").toString();
                    if (Uname.equals(UserName) || Email.equals(EmailAddress)){
                        Toast.makeText(Sgin_Up.this,"This user already exists",Toast.LENGTH_LONG).show();
                        break;
                    }else {
                        CreateUserProfile();
                    }
                }
            }
            }
        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

Expansions The code is working pretty fine and it checks the existing data as well as it displays Toast message, but after data still get into the database, I want to void the duplication data.

2 Answers

When creating new account or sign up process you can check does user already exists for example:

.createUserWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task) {
            boolean isNewUser = task.getResult().getAdditionalUserInfo().isNewUser(); 
           //retruns true if user is new 
          //false if user exits, move on login screen/forgot password etc.

        }
    })

And you have prevented creating account with same email address which actually makes unnecessary checking does email address exists on database because it is not possible to create new account with same email address anymore.

If you still want to check existing of email address on database you can run simple query:

databaseReference.orderByChild("Email").equalTo(email).addListenerForSingleValueEvent....

which will return data if email exists if not than there is no user with that email on database.

You're now creating inside the loop. This means it happens, each time it finds a node that is not for that new user. This obviously isn't what you want, since the new profile should only be created if none of the nodes matches the new user. So it has to be outside of the loop:

public void onDataChange(DataSnapshot dataSnapshot) {
    bool foundUser = false;
    final String Uname = name.getText().toString().trim();
    final String Email = emailAddress.getText().toString().trim();
    Iterator<DataSnapshot> dataSnapshots = dataSnapshot.getChildren().iterator();
    while (!foundUser && dataSnapshots.hasNext()) {
        DataSnapshot dataSnapshotChild = dataSnapshots.next();
        String EmailAddress = dataSnapshotChild.child("Email").toString();
        String UserName = dataSnapshotChild.child("UserName").toString();
        if (Uname.equals(UserName) || Email.equals(EmailAddress)){
            Toast.makeText(Sgin_Up.this,"This user already exists",Toast.LENGTH_LONG).show();
            foundUser = true;
        }
    }

    if (!foundUser){
        CreateUserProfile();
    }
}
Related