How to get data from firestore DB in outside of onSnapshot

Solution 1:

The data is loaded from Cloud Firestore asynchronously. Because this may take some time, the code after the callback immediately continues. Then when the data is available, Firestore calls your onSnapshot callback.

It's easiest to see what's happening by adding a few log statements:

console.log('Before adding listener');
this.db.collection('Users').doc(uid).get()
.then((docSnapshot) =>{
  console.log('Got data');
});
console.log('After adding listener');

When you run this code, it prints:

Before adding listener

After adding listener

Got data

This is probably not the order you expected. But it explains perfectly why your console.log(perfil) prints undefined: the data hasn't been loaded yet!

Because of this, all code that needs access to the data needs to be inside the onSnapshot callback. For example:

this.db.collection('Users').doc(uid).get()
.then((docSnapshot) =>{
  if (docSnapshot.exists) {
    this.db.collection('Users').doc(uid)
    .onSnapshot((doc) => {
        console.log(doc.data());
        perfil = doc.data();
        console.log(perfil);
    });
  }
});

For more on this, see:

  • get asynchronous value from firebase firestore reference
  • Why are the Firebase API asynchronous?
  • How to get a single document data in a Firebase Firestore (without promises)