1

I tried to get the document and the subcollection data at once in firestore.
And I used the async and await to deal with the forEach loop.
It still has some problem. The console.log 4 always executes first.

But what I expect the should be 1 -> 2 -> 3 -> 4.
Could anyone help me how to redesign my code?

let data = {};

toolboxesRef.get()
.then(async snapshot => {
  let toolboxes = [];
  // get toolbox
  await snapshot.forEach(async doc => {
    let toolbox = {};
    await toolboxesRef.doc(doc.id).collection('tags').get()
    .then(snapshot => {
      let tags = []
      snapshot.forEach(doc => {
        tags.push(doc.id);
        console.log(1)
      })
      toolbox.tags = tags;
      toolbox.id = doc.id;
      toolbox.data = doc.data(); 
      console.log(2)
    })
    console.log(3)
    toolboxes.push(toolbox)
  })
  console.log(4);
  data.toolboxes = toolboxes
  return data;
})

2 Answers2

1

export const asyncForEach = async (dataSnapshot, callback) => {
    const toWait = [];
    dataSnapshot.forEach(childSnapshot => {
        toWait.push(childFunction((childSnapshot)));
    });
    await Promise.all(toWait);
};

Hey i updated the code because it seems that Firebase integrate it's own foreach function. Then in order to resolve i decided to call every function and store the promise that it return into an array then i use Promise.all to resolve an array of async function

-1

You are using async operations inside forEach which doesn't work as you expect thm. You need to either use for..of or Promise.all. Try this version

const snapshot = await toolboxesRef.get();
const toolboxes = [];
for(const doc of snapshot) {
  const toolbox = {};
  const snapshot1 = await toolboxesRef.doc(doc.id).collection("tags").get();
  const tags = [];
  snapshot1.forEach(doc => {
    tags.push(doc.id);
    console.log(1);
  });
  toolbox.tags = tags;
  toolbox.id = doc.id;
  toolbox.data = doc.data();
  console.log(2);
  console.log(3);
  toolboxes.push(toolbox);
}
console.log(4);
data.toolboxes = toolboxes;
return data;

You might need to tweak few things here and there but you will get an idea.

Ashish Modi
  • 7,529
  • 2
  • 20
  • 35
  • Thanks for reply. I've try use `for...of` to iterate the snapshot. But it shows error messages that the snapshot is not iterable. Do you have any idea? Thank you. – charlestseng Jan 29 '20 at 10:27
  • I check the type of snapshot. It's object. – charlestseng Jan 29 '20 at 10:44
  • @charlestseng how were iterating in your case? You used `forEach` – Ashish Modi Jan 29 '20 at 11:15
  • Hmm it's weird. I found someone who use get() in Firebase also comment that it return the promise(promise). Do you know any other way to solve this problem? Should I try to convert the snapshot to array? https://stackoverflow.com/questions/53149138/use-async-foreach-loop-while-fetching-data-from-firestore#comment93189181_53149138 – charlestseng Jan 29 '20 at 11:28
  • I found an answer on this site. I should use `snapshot.docs` not only `snapshot`. https://medium.com/@vladfr/use-cloud-firestore-with-async-bce875af0183 – charlestseng Jan 29 '20 at 11:42