Firebase数据无法通过innerHTML渲染表格的技术求助
Let’s break down your issues and walk through the fixes step by step.
Why Your First Snippet Has an Empty file11
The root problem here is asynchronous execution. When you call getDataToUsers.once("value"), Firebase runs this request in the background—it doesn’t pause your loop to wait for the data to come back. By the time your code reaches tableBody.innerHTML = file11, none of the once() callbacks have finished running yet, so file11 stays empty. The console logs from the callbacks might even show up after the console.log("data of table file11:",file11) line, which confirms the async timing issue.
How to Fetch User Names from the users Node (Instead of Using content)
Your second snippet works because it uses synchronous data directly from the review node, but we need to adjust it to properly handle the async fetch of user data from the users node. Here are two solid solutions:
Solution 1: Use Async/Await (Cleanest Modern Approach)
This approach pauses the loop until each user’s data is fetched, ensuring we have all the info we need before building the table:
async function loadTables(){ refReview.on("value", async function(snap){ const data = snap.val(); const tableRows = []; // Use an array to collect rows efficiently for(const key in data){ console.log("keys retrieved", data[key].revieweeID); const idOfReviewee = data[key].revieweeID; // Wait for the user data to load before moving on const userSnap = await firebase.database().ref("users").child(idOfReviewee).once("value"); const userData = userSnap.val(); console.log(userData.firstname); // Add the formatted row to our array tableRows.push(`<tr><td>${userData.firstname}</td><td>${userData.lastname}</td></tr>`); } // Combine all rows into one string and render tableBody.innerHTML = tableRows.join(''); }); }
Key Changes:
- Added
asyncto therefReviewcallback so we can useawaitinside it. - Used
awaitwithonce("value")to pause the loop until each user’s data is fetched. - Swapped string concatenation for an array (
tableRows)—this is more efficient than repeatedly modifying a string. - Used template literals (backticks
`) to make the HTML row code cleaner and easier to read.
Solution 2: Use Promise.all (For Older Environments)
If you need to support environments without async/await, use Promise.all to wait for all user data requests to complete at once:
function loadTables(){ refReview.on("value", function(snap){ const data = snap.val(); const userPromises = []; // First, collect all promises for user data requests for(const key in data){ const idOfReviewee = data[key].revieweeID; userPromises.push( firebase.database().ref("users").child(idOfReviewee).once("value") ); } // Wait for all user data to load before building the table Promise.all(userPromises).then(function(userSnaps){ const tableRows = []; // Match each resolved user snapshot to its review entry Object.keys(data).forEach(function(key, index){ const userData = userSnaps[index].val(); tableRows.push(`<tr><td>${userData.firstname}</td><td>${userData.lastname}</td></tr>`); }); tableBody.innerHTML = tableRows.join(''); }); }); }
Why This Works:
- We create an array of promises, each representing a request for a user’s data.
Promise.allwaits until every promise in the array resolves, then gives us an array of all user snapshots.- We loop through both the original review data and resolved user snapshots to build our rows, then render the table once all rows are ready.
Either solution will fix your empty file11 issue and let you render the table with the correct user names from the users node.
内容的提问来源于stack exchange,提问作者kenny

