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.