You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase实时数据库嵌套读取多引用:表格无数据但日志可读

Firebase实时数据库嵌套读取后表格无法渲染问题解决

问题描述

使用JavaScript操作Firebase实时数据库时,尝试嵌套读取多个引用,控制台能正常打印数据,但页面表格无法渲染对应内容,疑惑Firebase实时数据库是否不支持嵌套读取,寻求解决方法。

相关代码(原代码)

var refEmanet = firebase.database().ref('emanet');
// Add ref of child if any
refEmanet.on('value', function(snapshot) {
    var icerik="" 
    var no=1;
    snapshot.forEach((child)=>{
        
        if(child.val().geriVermeTarihi!=0){
            dataArray[no]=child.val();
                  console.log(child.val().isbn);
        icerik+='<tr>';
            icerik+='<td>'+no+'</td>';
const dbRef2 = firebase.database().ref();
            dbRef2.child("kitaplar").child(child.val().kitapId).get().then((snapshot2) => {
                if (snapshot2.exists()) {
                    var no1=0;
                        if(snapshot2.key==child.val().kitapId){
                    console.log(snapshot2.val().kitapAdi);
                    icerik+='<td>'+snapshot2.val().kitapAdi+'</td>'; 
                    no1++;
                    }
                    
                    

                } else {
                    console.log("No data available");
                }
                }).catch((error) => {
                    console.error(error);
                });
           
            icerik+='<td>'+child.val().isbn+'</td>';

            const dbRef3 = firebase.database().ref();
            dbRef3.child("ogrenciler").child(child.val().ogrId).get().then((snapshot3) => {
                if (snapshot3.exists()) {
                    
                    console.log(snapshot3.val());
                    icerik+='<td>'+snapshot3.val().ad+' '+snapshot3.val().soyad+'</td>'; 
                    

                } else {
                    console.log("No data available");
                }
                }).catch((error) => {
                    console.error(error);
                });

//            icerik+='<td>'+child.val().ogrId+'</td>';
            icerik+='<td>'+child.val().emanetTarihi+'</td>';
            icerik+='</tr>';
            no++;  
        }


    });

   console.log(snapshot.val());
    $('#ex-table').append(icerik);


});

数据截图

数据截图

问题原因

Firebase实时数据库支持嵌套读取,问题出在异步操作的执行顺序上:

  • 你使用的get()方法是异步的,代码会先执行完所有同步逻辑(拼接icerik的同步部分、将icerik追加到DOM),此时嵌套的get()请求还未完成,对应的icerik+=...代码根本没机会执行。
  • 控制台能打印数据是因为后续异步请求完成后触发了回调,但此时DOM已经渲染完毕,修改icerik不会再更新页面内容。

解决方法

通过Promise.all统一处理异步请求,等待所有关联数据加载完成后再渲染表格,保证HTML拼接的完整性:

var refEmanet = firebase.database().ref('emanet');
refEmanet.on('value', function(snapshot) {
  // 收集所有行的异步处理Promise
  const rowPromises = [];
  let no = 1;

  snapshot.forEach((child) => {
    if (child.val().geriVermeTarihi !== 0) {
      const emanetData = child.val();
      // 同时发起书籍和学生数据的请求,用Promise.all等待两者完成
      const rowPromise = Promise.all([
        firebase.database().ref(`kitaplar/${emanetData.kitapId}`).get(),
        firebase.database().ref(`ogrenciler/${emanetData.ogrId}`).get()
      ]).then(([kitapSnapshot, ogrenciSnapshot]) => {
        let row = `<tr>`;
        row += `<td>${no}</td>`;
        
        // 拼接书籍名称
        if (kitapSnapshot.exists()) {
          row += `<td>${kitapSnapshot.val().kitapAdi}</td>`;
        } else {
          row += `<td>无书籍数据</td>`;
        }
        
        row += `<td>${emanetData.isbn}</td>`;
        
        // 拼接学生姓名
        if (ogrenciSnapshot.exists()) {
          const ogrenci = ogrenciSnapshot.val();
          row += `<td>${ogrenci.ad} ${ogrenci.soyad}</td>`;
        } else {
          row += `<td>无学生数据</td>`;
        }
        
        row += `<td>${emanetData.emanetTarihi}</td>`;
        row += `</tr>`;
        no++;
        return row;
      }).catch((error) => {
        console.error(error);
        return `<tr><td colspan="5">加载出错</td></tr>`;
      });

      rowPromises.push(rowPromise);
    }
  });

  // 等待所有行的数据都准备好后,一次性渲染到表格
  Promise.all(rowPromises).then((rows) => {
    const icerik = rows.join('');
    $('#ex-table').html(icerik); // 使用html()替换内容,避免重复追加
  });
});

代码说明

  1. Promise.all批量处理异步请求:同时发起书籍和学生数据的请求,减少等待时间,确保所有关联数据加载完成后再生成行HTML。
  2. 统一渲染DOM:所有行的HTML都准备好后,一次性插入表格,避免异步操作导致的内容缺失。
  3. 替换而非追加:使用html()替换表格内容,避免每次数据更新时重复追加旧内容。

内容的提问来源于stack exchange,提问作者Erdem SELVİ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 13:20:30