Chen
Chen

Reputation: 970

onSnapshot, forEach, and get() synchronously on Firebase

I am using firebase's .onSnapshot to grab the ID of the users currently online, and store each ID to an array. I successfully deployed .onSnapshot to get the ID of the online users, but I return an empty array at the end

var learning_language;
db.collection(ll_profile).doc(user_uid).get().then(function(doc) {
  learning_language = doc.data().learning_language;
})

db.collection(ns_status).where("state", "==", "online").onSnapshot(function(snapshot) {
  var ns_match = [ ];
  snapshot.forEach(function(userSnapshot) {
    db.collection("ns_profile").doc(userSnapshot.id).get().then(function(doc) {
      spoken_language = doc.data().spoken_language;
      if (learning_language == spoken_language) {
        ns_match.push(userSnapshot.id);
        console.log(ns_match);
      }
    })
  })
  return (ns_match);

What I am trying to do is to first define the learning_language retrieved from the collection ll_profile with the current user's ID named user_uid.

Then .onSnapshot listens to another group of users' online state (which automatically updates if an user is online or offline) inside ns_status collection. After, the returned online user from .onSnapshot is checked if the spoken_language field inside their document (named with their corresponding uid) matches with learning_language defined earlier. If it matches, then store the uid into the array of ns_match.

The values inside ns_match are correct. I think .get() executes asynchronously. That is why ns_match is returned empty.

How should I return ns_match at the end with all the values stored properly?

Thanks in advance.

Upvotes: 0

Views: 1962

Answers (2)

Shady Alzayat
Shady Alzayat

Reputation: 81

wrapping in a promise is the correct move. However, remember that snapshot returns metadata about your result. Particularly, snapshot.size. One can use that value to count records, inside the foreach method, or compare the destination array length with the snapshot.size value

Upvotes: 0

Tanmay_vijay
Tanmay_vijay

Reputation: 619

function getMatches() {
  return new Promise(resolve => {
    db.collection(ll_profile).doc(user_uid).get()
      .then(function(doc) {
        var learning_language = doc.data().learning_language;
        db.collection(ns_status)
          .where("state", "==", "online")
          .onSnapshot(function(snapshot) {
            var ns_match = [];
            snapshot.forEach(function(userSnapshot) {
              db.collection("ns_profile")
                .doc(userSnapshot.id)
                .get()
                .then(function(doc) {
                  spoken_language = doc.data().spoken_language;
                  if (learning_language == spoken_language) {
                    ns_match.push(userSnapshot.id);
                    console.log(ns_match);
                  }
                });
            });
            resolve(ns_match);
          });
      });
  });
}


getMatches().then(ns_matches => console.log(ns_matches));

Upvotes: 1

Related Questions