Firebase数据库新增子节点返回null,刷新后恢复正常求助
解决Firebase child_added首次获取数据为null的问题
我之前也碰到过一模一样的情况,大概率是数据写入逻辑和Firebase的事件触发机制不匹配导致的,下面给你拆解原因和对应的解决办法:
问题根源
当你往session节点添加子节点时,如果是先创建空节点/只写入部分字段,之后再补充其他字段,Firebase的child_added事件会在节点第一次被创建时立刻触发——这时候lon、lat这些字段还没被写入数据库,所以snap.child("lon").val()自然会返回null。而刷新页面时,节点已经存储了完整的所有字段,所以读取就正常了。
解决方案
方案1:一次性写入完整数据
最直接的办法是添加子节点时,用push().set()一次性把所有需要的字段都写入,这样child_added会在完整数据提交到数据库后才触发,就能拿到正确的数值:
// 示例:一次性写入完整的子节点数据 firebase.database().ref('session').push({ dur: 你的时长数值, lat: 你的纬度数值, lon: 你的经度数值 });
方案2:监听child_changed事件补充数据
如果因为业务需求必须分步写入数据,可以同时监听child_changed事件,当节点数据更新时重新获取完整数据,同时在处理前判断字段是否有效,避免渲染null值:
// 初始化Firebase部分保持不变 var database = firebase.database().ref().child("session"); // 统一处理子节点新增和更新的逻辑 function renderSessionData(snap) { var dur = snap.child("dur").val(); var lat = snap.child("lat").val(); var lon = snap.child("lon").val(); // 先判断所有字段是否都存在,再执行渲染 if (dur !== null && lat !== null && lon !== null) { var para = document.createElement("p"); var node = document.createTextNode(lon); para.appendChild(node); document.getElementById("div1").appendChild(para); } } // 同时监听子节点新增和更新事件 database.on("child_added", renderSessionData); database.on("child_changed", renderSessionData);
额外小技巧
你也可以直接读取整个节点的快照值,代替逐个child读取的方式,代码会更简洁:
function renderSessionData(snap) { var sessionData = snap.val(); // 用可选链操作符判断字段是否存在 if (sessionData?.dur && sessionData?.lat && sessionData?.lon) { var para = document.createElement("p"); var node = document.createTextNode(sessionData.lon); para.appendChild(node); document.getElementById("div1").appendChild(para); } }
内容的提问来源于stack exchange,提问作者Joseph Little
相关产品推荐
相关产品推荐

