Firebase Realtime Database数组正确增删方法
Firebase Realtime Database 关注关系存储与增删操作指南
现有代码的问题
你当前的写法会直接覆盖原有全部数组数据,两个测试账号下运行正常只是首次写入时followers和following字段本身为空,当你关注第二个、第三个用户时,传入的单元素数组会直接替换掉之前存储的所有粉丝/关注记录,不会做追加操作。
注意:Firebase Realtime Database 本身不推荐使用数组存储多对多关系(比如粉丝/关注),数组的全量替换逻辑在多客户端并发操作时极易出现数据覆盖问题,且每次增删都需要读取全量数组,性能很差。
推荐存储结构
官方推荐使用键值对集合结构存储粉丝/关注关系,将followers和following从数组改为对象,以用户UID作为键,值可以存true或者关注时间戳,结构示例:
{ "Users": { "用户A的uid": { "followers": { "用户B的uid": 1718000000000, "用户C的uid": 1718000123456 }, "following": { "用户D的uid": 1717987654321 } } } }
这种结构的优势:
- 增删单个关注关系不会影响其他已有数据
- 不存在并发覆盖问题,多个用户同时关注同一个账号不会丢数据
- 判断是否关注时直接通过UID查对应键是否存在即可,不需要遍历全量列表
正确的新增(关注)实现
不要直接给followers/following整个字段赋值,通过路径定位到具体UID的子字段做更新,同时可以把两次更新合并为一次原子操作,避免出现一边加了粉丝、另一边没加关注的脏数据:
async followUser() { const targetUid = this.$route.params.uid const currentUid = store.currentUser.uid const updateMap = {} // 给被关注用户添加当前用户的粉丝记录 updateMap[`Users/${this.profileKey}/followers/${currentUid}`] = Date.now() // 给当前用户添加对目标用户的关注记录 updateMap[`Users/${store.currentUserKey}/following/${targetUid}`] = Date.now() // 根节点执行批量原子更新 await update(ref(db), updateMap) }
正确的删除(取关)实现
Firebase Realtime Database 中给字段赋值null等价于删除该字段,同样用原子批量更新即可:
async unfollowUser() { const targetUid = this.$route.params.uid const currentUid = store.currentUser.uid const updateMap = {} // 删除被关注用户下的当前用户粉丝记录 updateMap[`Users/${this.profileKey}/followers/${currentUid}`] = null // 删除当前用户下的目标用户关注记录 updateMap[`Users/${store.currentUserKey}/following/${targetUid}`] = null await update(ref(db), updateMap) }
为什么不推荐数组操作
如果硬要使用数组存储,你必须先读取当前节点下的全量数组数据,在本地完成push/splice修改后,再把整个数组写回数据库。这种方式有两个致命问题:
- 并发场景下必然丢数据:两个用户同时关注同一个账号时,双方都读到旧的空数组,各自写入后只会保留最后一次写入的记录
- 性能差:当用户粉丝/关注量达到几百上千时,每次操作都要传输几KB甚至几MB的全量数组,浪费带宽、拉高延迟
内容的提问来源于stack exchange,提问作者user9741470
相关产品推荐
相关产品推荐

