Netanel Malichi
Netanel Malichi

Reputation: 33

I need to wait until listener changes boolean from null to false/true java

I have a Firebase listener that checks if User exists (Im making login/signup using Firebase database) in order to tell if the username is taken or not, the problem is that it takes 2 clicks on the Signup button for it to work, because the listener cant tell if username exists or not fast enough, only on second click when it already decided for the first click it is possible to signup, but then again it does not really check the username of the second click (If I change username now, even if it is taken it will work)

database = FirebaseDatabase.getInstance();
    DatabaseReference myRef = database.getReference("Users/" +    usernameEt.getText().toString() +"/password");
    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String value = dataSnapshot.getValue(String.class);
            if(value != null) {
                Toast.makeText(getApplicationContext(), "Username Taken", Toast.LENGTH_SHORT).show();
                clear = false;
            }else
                clear = true;
        }
        @Override
        public void onCancelled(DatabaseError error) {
            // Failed to read value
            clear = false;
            Toast.makeText(getApplicationContext(), "Internet Error", Toast.LENGTH_SHORT).show();
        }
    });

    //insert check if clear has value

    if(!clear) //TODO FIX takes time to the listener to do the job
        return false;

clear is a Boolean type var and is null at the first time this code runs, this code is for checking if username is taken or not

Upvotes: 1

Views: 789

Answers (1)

injung
injung

Reputation: 84

Maybe your code looks like this:

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    signUpBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (checkUserExists()) {
                ...
            } else {
                signUp();
            }
        }
    }
}

private boolean checkUserExists() {
    database = FirebaseDatabase.getInstance();
    DatabaseReference myRef = database.getReference("Users/" +    usernameEt.getText().toString() +"/password");
    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String value = dataSnapshot.getValue(String.class);
            if(value != null) {
                Toast.makeText(getApplicationContext(), "Username Taken", Toast.LENGTH_SHORT).show();
                clear = false;
            }else
                clear = true;
        }
        @Override
        public void onCancelled(DatabaseError error) {
            // Failed to read value
            clear = false;
            Toast.makeText(getApplicationContext(), "Internet Error", Toast.LENGTH_SHORT).show();
        }
    });

    //insert check if clear has value

    if(!clear) //TODO FIX takes time to the listener to do the job
        return false;
}

private void signUp() {
    ...
}

You should change it to:

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    signUpBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            checkUserExists();
        }
    }
}

private boolean checkUserExists() {
    database = FirebaseDatabase.getInstance();
    DatabaseReference myRef = database.getReference("Users/" +    usernameEt.getText().toString() +"/password");
    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String value = dataSnapshot.getValue(String.class);
            if(value != null) {
                Toast.makeText(getApplicationContext(), "Username Taken", Toast.LENGTH_SHORT).show();
            } else {
                signUp(); // sign up here
            }
        }
        @Override
        public void onCancelled(DatabaseError error) {
            Toast.makeText(getApplicationContext(), "Internet Error", Toast.LENGTH_SHORT).show();
        }
    });
}

private void signUp() {
    ...
}

Also you can block user input while checking user data:

private boolean checking = false; // added

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    signUpBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (checking) return; // added
            checkUserExists();
            checking = true; // added
        }
    }
}

private boolean checkUserExists() {
    database = FirebaseDatabase.getInstance();
    DatabaseReference myRef = database.getReference("Users/" +    usernameEt.getText().toString() +"/password");
    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            checking = false; // added
            String value = dataSnapshot.getValue(String.class);
            if(value != null) {
                Toast.makeText(getApplicationContext(), "Username Taken", Toast.LENGTH_SHORT).show();
            } else {
                signUp(); // sign up here
            }
        }
        @Override
        public void onCancelled(DatabaseError error) {
            checking = false; // added
            Toast.makeText(getApplicationContext(), "Internet Error", Toast.LENGTH_SHORT).show();
        }
    });
}

private void signUp() {
    ...
}

Hope it works.

Upvotes: 1

Related Questions