MiGu3X
MiGu3X

Reputation: 119

Wait for callback to run before throwing result firestore

Im using react-native, Expo and firebase firestore I have tables

products

items

I want to get all the products and the amount of items that product has. Code is:

export const getProducts = (callback) => {
  const db = firebase.firestore();

  let products = [];

  db.collection('products').get().then((productsSnapshot) => {
    productsSnapshot.forEach((_product, index, array) => {
    let product = _product.data()

    product.id = _product.id;
    getItems(product._id, (items, error) => {
      product.count = items.length;
      products.push(product);
    });
  });
  callback(products, null);
  ...

export const getItems = (productId, callback) => {
  const db = firebase.firestore();
  let items = [];

  db.collection('items').where('productId', '==', productId).get()
  .then((itemsSnapshot) => {
    itemsSnapshot.forEach((_item) => {
      let item = _item.data();
      item.id = _item.id;

      items.push(item);
    });

    callback(items, null);
    ...

The problem I have is the callback on getItems runs after and .count never gets a value.

I tried async await but I couldn't understand how to use it and threw errors while using firestore. Is using callbacks a bad idea? What is the way it should be done?

Upvotes: 1

Views: 265

Answers (1)

Jason Byrne
Jason Byrne

Reputation: 1619

You could surround it by a promise, and put the callback in the then. Something like this...

new Promise((resolve, reject) => {
    db.collection('products').get().then((productsSnapshot) => {
        productsSnapshot.forEach((_product, index, array) => {
            let product = _product.data()
            product.id = _product.id;
            getItems(product._id, (items, error) => {
                product.count = items.length;
                products.push(product);
            });
        });
        resolve();
    });
}).then(function () {
    callback(products, null);
});

Upvotes: 1

Related Questions