刷新浏览器导致Firebase Realtime Database子节点内容被覆盖的问题
问题原因分析
嘿,这个问题其实很好理解~你代码里的user_number变量是存在浏览器内存中的,每次刷新浏览器,页面所有JS代码都会重新执行,这个变量就会被重新初始化为0。刷新后你第一次提交新用户时,user_number++变成1,自然就会覆盖掉原来的user 1节点内容啦!
而不刷新浏览器的时候,user_number一直在内存里累加,每次点击都会递增,所以能正常创建user 1、user 2这类新节点,不会出现覆盖问题。
解决方案
这里给你几种可行的解决办法,按推荐程度排序:
1. 使用Firebase内置的push()方法(最推荐)
Firebase Realtime Database提供了push()方法,它会自动生成一个唯一的、带时间戳的节点键,完全不需要你自己维护序号,既简单又能避免覆盖问题。
修改你的submitClick函数即可:
function submitClick(x){ var firebaseRef = firebase.database().ref(); // 用push()替代手动创建序号节点 firebaseRef.push(x); }
这样每个新用户都会被添加为一个独立的子节点,键类似-NxXxxxxxxxxx,绝对不会重复覆盖。
2. 从数据库读取当前最大序号(保留user 1、user 2命名)
如果你一定要保留user 1、user 2这种命名规则,那需要在页面加载时,从数据库里读取现有的最大用户序号,初始化user_number:
var user_number = 0; // 页面加载时获取当前最大的用户序号 firebase.database().ref() .orderByKey() .startAt("user ") // 只筛选以"user "开头的节点 .limitToLast(1) // 取最后一个(也就是序号最大的) .once("value") .then(function(snapshot) { snapshot.forEach(function(childSnapshot) { var key = childSnapshot.key; // 比如"user 3" // 提取序号数字并赋值给user_number user_number = parseInt(key.split(" ")[1]); }); });
这样刷新页面后,user_number就会从现有最大的序号开始累加,不会重置为0,也就不会覆盖旧节点了。
3. 使用用户唯一标识作为节点名
如果你的用户名(username)是唯一的,也可以直接用用户名作为节点名,这样天然不会重复:
function submitClick(x){ var firebaseRef = firebase.database().ref(); // 用username作为节点键 firebaseRef.child(x.Username).set(x); }
⚠️ 注意:Firebase的节点键不能包含. # $ [ ] /这些特殊字符,所以如果允许用户输入这些字符,需要先对用户名做转义处理哦。
内容的提问来源于stack exchange,提问作者Suren
相关产品推荐
相关产品推荐

