简体   繁体   中英

Firebase getting all docs from collections and docs of subcollection

i have this schema:

我有的架构

And I try to put a table with the documents and just below the documents of the subcollection, something similar to this:

我想要的是

I'm using this code, but in practice it doesn't display the data in order, it first puts the documents in the collection together and then the docs for the subcollections, I get this:

我得到这个

getDocs(collection(db, "users")).then(docSnap => {
  let table = document.getElementById('myTable')
  table.innerHTML = ''

  docSnap.forEach((doc) => {

    let data = doc.data();
    let row = `<tr>                           
                        <td>${data.contador}</td>
                        <td>${data.email}</td>
                        <td>${data.pass}</td>
                        </tr>`;

    let table = document.getElementById('myTable')
    table.innerHTML += row // 

    getDocs(collection(db, "users", doc.id, "fcm_tokens")).then(docSnapFCM => {
      docSnapFCM.forEach((docFCM) => {
        let data2 = docFCM.data();
        let row2 = `<tr class="table-success">
                        <td>${data2.contador}</td>
                        <td>${data2.device_type}</td>
                        <td>${data2.fcm_token}</td>
                        </tr>`;

        table.innerHTML += row2

      });
    });
  });
});

Thats because forEach is running synchronous and the fetch request from getDocs is running asynchronous. The asynchronous code (the getDocs function just takes more time to execute than the forEach loop does which causes that all your user rows are added to your table before the answer comes from your firestore.

To solve this issue you have to await each getDocs call in your forEach function with the async / await keywords and Promise.all .

Example:

Not a one to one copy of your code but I hope it helps you learning

const createTable = async () => {
    // gather your user data
    const users = (await getDocs(collection(db, 'users')).docs.map((doc) => doc.data());


    // loop over the user data in async
    Promise.all(
        users.forEach(async (user) => {
            // do your table adding stuff here
            let row = '<tr>...'

            const subcollection = (await getDocs(collection(db, "users", doc.id, "fcm_tokens"))).docs.map((doc) => doc.data());
        
            // do your subcollections table adding stuff here
            subcollection.forEach((doc) => {
                // some table row adding with your data
            });
        });
    )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM