0

I am new in database systems and what I am trying to do is to check whether the e-mail entered by the user during login exists in the database or not. I use Firebase Databse. So, the code I have written is this:

function login(){
    var e_mail = document.getElementById("e-mail").value;
    rootRef = firebase.database().ref();
    rootRef.orderByChild("E_mail").on("child_added", function(snapshot){
        lst.push(snapshot.val().E_mail);
        //console.log(lst);
    })
    console.log(lst);
}

let lst = [];
login_btn.onclick = function() {login()};

I want to fetch all e-mails from the database, add them in the list and then loop through that list. Maybe this is not the best way, but that's what I'm working on. I could also just say if (snapshot.val().E_mail == e_mail){alert("there is such a user");}but the problem I have encountered and want to deal with is not that, it's the "callback" function inside login function. When I console the list in the outer function it shows an empty list as it does not run the inner function until it is done with the outer one. I understand this. But how can I avoid or fix this. I want to get the full list of e-mails to be able to loop through it then. Also, I don't know how to end the "loop" in Firebase, because it is sort of looping when it gets the e-mails. So I would like to stop at the moment when it finds a matching e-mail.

Suren
  • 173
  • 3
  • 11
  • loop through them where you have them ... in the callback – Jaromanda X May 28 '18 at 02:13
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Sebastian Simon May 28 '18 at 02:30
  • Yes, I tried that as well, but the problem with that is that I need to terminate taking the snapshots of the e-mails as soon as I find a matching one, because I am getting as many alerts (whether the user exists or not) as many e-mails there is in the database. @JaromandaX – Suren May 28 '18 at 02:42
  • are you saying you need to "cancel" (for want of a better term) the `.on("child_added"` handler? – Jaromanda X May 28 '18 at 02:47
  • yes, sort of. Although I doubt that it is possible. @JaromandaX – Suren May 28 '18 at 10:21

1 Answers1

1

You're downloading all users to see if one name exists already. That is a waste of bandwidth.

Instead you should use a query to match the email you're looking for, and only read that node:

rootRef.orderByChild("E_mail").equalTo(e_mail).once("value", function(snapshot){
    if (snapshot.exists()) {
        // A node with the requested email already exists
    }
})

In general, if you need to process all nodes, you'll want to use a value event, which executes for all matching nodes at once. So to get all users from the database, add them to a list, and then do something with that list:

rootRef.orderByChild("E_mail").once("value", function(snapshot){
    var list = [];
    snapshot.forEach(function(childSnapshot) {
        list.push(childSnapshot.val());
    });
    console.log(list); // this will display the populated array
})

Note that you won't be able to access the list outside of the callback. Even if you declare the variable outside of the callback, it will only be properly populated inside the callback. See Xufox' comment for a link explaining why that is.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807