tomasxboda
tomasxboda

Reputation: 539

Loading data from Firebase asynchronously

I am developing a business manager web app in React with Firebase back-end. I am also coding a local API to simplify Firebase functions. I created this method, which loads data from a Firebase collection and returns an array of documents.

getDocuments(collection) {
    var documents = [];

    firebase.firestore().collection(collection).get().then(snapshot => {
        snapshot.forEach(doc => {
            documents.push(doc);
        });
    }).then(() => {
        return documents;
    })
}

However, when I call the method and assign it to a variable which I later print to the console, it says undefined.

var employees = getDocuments("employees");
console.log(employees);

What I want to do is to use .then() after calling the method to print the already loaded data to the console. Something like this:

var employees = getDocuments("employees").then(response => {
    console.log(response);
})

Any help would be appreciated. Thank you.

Upvotes: 1

Views: 356

Answers (2)

Thomas Kuhlmann
Thomas Kuhlmann

Reputation: 1003

Your getDocuments function seems to be unnecessarily complicated. This:

   getDocuments(collection) {    
          return firebase.firestore().collection(collection).get().then(snapshot=>snapshot.docs)
    }

yields exactly the same intended result (an Array of docs wrapped in a promise) as your function but performs faster since it skips looping through all the documents in the snapshot https://firebase.google.com/docs/reference/js/firebase.firestore.QuerySnapshot#docs

Afterwards just extract the value from the Promise returned by this function in your preferred way:

Option 1 (async/await)

let employees= await getDocuments('employees')
console.log(employees)

Option 2 (chaining)

let employees =[] 
getDocuments('employees').then(response => {
    employees=response 
    console.log(employees) 
})

Explanation

When you are doing this:

var employees = getDocuments("employees").then(response => {
    console.log(response);
})

you aren't receiving any value from getDocuments since you didn't return anything in the first place.

getDocuments(collection) {
    var documents = [];

    firebase.firestore().collection(collection).get().then(snapshot => {
        snapshot.forEach(doc => {
            documents.push(doc);
        });
    }).then(() => {
        return documents; <-- this is returning the value of documents to the parent scope which is 'getDocuments', since the 'then' is related to the 'get' function
    })
}

Upvotes: 1

Guillaume Munsch
Guillaume Munsch

Reputation: 1283

You should assign employees in the then like this

var employees = [];
getDocuments("employees").then(response => {
    employees = response;
    console.log(response);
})

Or if you are in an asynchronous function, you could go for something like this

var employees = await getDocuments("employees");
console.log(employees);

But the await keyword has to be done in an async function

Upvotes: 0

Related Questions