0

I've made a simple class that returns the data downloaded from firebase. The issue is that if I console.log data in the class, it gives data as expected. However, if I import this class anywhere else and try to use it, it returns data as undefined.

Can you explain what's wrong?

My getCollection func in class dbAPI (data is correct)

getCollection(collection) {
    dataBase
      .collection(collection)
      .get()
      .then(querySnapshot => {
        let data = querySnapshot.docs.map(doc => doc.data())
        console.log(data)
        return data
      })
      .catch(function(error) {})
  }

The way I try to get data (data is undefined here)

componentDidMount() {
  const db = new dbAPI()
  let data = db.getCollection("collectionName")
  this.setState({ data })}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
A.Zawadzki
  • 33
  • 4
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Kevin B Sep 18 '19 at 16:06

2 Answers2

0

The issue is that you're trying to return data from a callback to a synchronous function, which is impossible (link). You need to either promisify your getCollection function, or use async/await. If you want to convert your code to use async/await, check out this link. I put an example below. Basically, you need to await for the get request to get the data, then perform your transformation. After performing that transformation, you can return data.

async getCollection(collection) {
  const collectionRef = dataBase.collection(collection);
  try {
    const dataSnapshot = await collectionRef.get();
    const data = querySnapshot.docs.map(doc => doc.data());
    console.log(data);
    return data;
  } catch (err) {
    console.log(err);
  }      
}

In your componentDidMount, you must add async/await keywords to the appropriate functions. Async needs to go to the top to mark componentDidMount as async, and you need to await the data from the function call db.getCollection.

async componentDidMount() {
  const db = new dbAPI()
  const data = await db.getCollection("collectionName")
  this.setState({ data })
}
technogeek1995
  • 3,185
  • 2
  • 31
  • 52
0

Thanks to you I've managed to do it, really appreaciate your help, my solution:
getCollection:

 async getCollection(collection) {
let data = null
await dataBase
  .collection(collection)
  .get()
  .then(querySnapshot => {
    data = querySnapshot.docs.map(doc => doc.data())
  })
  .catch(function(error) {
    console.error(`Data fetch failed: \n${error}`)
    data = "ERROR"
  })
return data}

getting data:

  async componentDidMount() {
const db = new Database()
const data = await db.getCollection("collectionName")
this.setState({ ...data })}
A.Zawadzki
  • 33
  • 4