1

I am developing an android application and using Firebase to store my data. I want to query the firebase instance to check whether the user entered email address matches one of the email in Firebase. Attaching the Firebase backend data.

Firebase database

My requirement is, I want to loop through the "guardians", which is the direct child of the Database instance and check whether the user entered email matches any one of the email address in that child. In the attached image, if the user entered email matches either "ram@gmail.com" or the other one, I want to do something.

databaseReference = FirebaseDatabase.getInstance().getReference().child("guardians");
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot data: dataSnapshot.getChildren()){
                if (**I am unable to figure out how to search through entire guardians child for the email**) {

                } else {

                }
              }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

I am unable to figure out how to search through the entire guardians child to see whether the email matches the user entered email. Any help is appreciated. Thanks in advance.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Ramji Seetharaman
  • 524
  • 4
  • 7
  • 24

1 Answers1

1

If you made your current approach work (it's a matter of adding the correct if statement) you'd be downloading the entire list of users, just to check if a specific email address is in use. This is incredibly wasteful of bandwidth, especially as your user list grows.

You should instead use a Firebase Database query to only return the user with the requested email address:

databaseReference = FirebaseDatabase.getInstance().getReference().child("guardians");
Query query = databaseReference.orderByChild("guardianEmail").equalTo("guardian@example.com");
query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                ... the email address is already in use
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException(); // don't ignore errors
        }
    });

Be sure to add an index for the guardianEmail field, as otherwise you'll still end up downloading all data for the query.

Note that this topic has been covered quite a few times before, and there are better ways to do this check. Most of these involve creating a so-called inverted index, where you use the (encoded) email address of the user as the key. With that structure you can prevent duplicates in Firebase's server-side security rules, which is even more efficient.

For more on this and other approaches, see:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks a lot for your suggestion. My requirement is like I want when an user tries to register to the application, the user entered email should not match with any of the email in the guardians child. – Ramji Seetharaman Jul 07 '17 at 04:19
  • I tried the approach which you suggested. But even if I enter en email that is there in the guardians child list, it goes to the else block. Is it because I'm missing the userID?. My structure to Firebase is the Database Instance --> guardians ---> user ID -----> guardianEmail – Ramji Seetharaman Jul 07 '17 at 04:20
  • I just ran this code: `ref.orderByChild("name").equalTo("name2").addListenerForSingleValueEvent(new ValueEventListener() { public void onDataChange(DataSnapshot dataSnapshot) { System.out.println(dataSnapshot.exists()); }`. It prints `true` when there is a matching name and `false` when there isn't. – Frank van Puffelen Jul 07 '17 at 04:33
  • That was my bad. I was looping through the wrong child. Works perfectly fine. You saved me some time! Thanks loads Frank! Nice to get in touch with you! – Ramji Seetharaman Jul 07 '17 at 04:48