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

Discord.js开发机器人集成Firebase实时数据库数据被重置问题求助

问题根本原因

  1. 异步逻辑错误:Firebase Realtime Database的ref.on('value', callback)是持续监听方法,不返回Promise,你加的await完全不生效,代码会不等读取结果返回就直接执行后续的set操作,此时profileData和guildData还没被赋值,直接写入就会覆盖原有数据。
  2. Guild实例缺失兜底逻辑:读取Guild数据时没有判断空值,当Guild数据不存在时guildData为null,直接写入会清空对应路径的所有数据。
  3. 监听器滥用:单次读取数据使用on会创建持续触发的监听器,多次调用会造成内存泄漏,也可能导致回调重复执行覆盖数据。

修复方案

直接替换sendData.js的代码为以下版本:

const database = require('../firebase.js')
const User = require('../data/user.js')
const Guild = require('../data/guild.js') // 引入你定义的Guild类

module.exports = async (Discord, client, message) => {
  const guildID = message.guild.id;
  const userID = message.author.id;

  if (userID === client.user.id) return;

  // 用once替代on做单次读取,once返回Promise可正常await
  const userSnapshot = await database.ref(`/Users/${userID}-${guildID}`).once('value')
  let profileData = userSnapshot.val() ?? new User(userID, guildID)
  
  const guildSnapshot = await database.ref(`/Guilds/${guildID}`).once('value')
  let guildData = guildSnapshot.val() ?? new Guild(guildID)

  // 确认读取到数据后再写入,避免空值覆盖
  await database.ref(`/Users/${userID}-${guildID}`).set(profileData)
  await database.ref(`/Guilds/${guildID}`).set(guildData)
}

额外优化建议

  • 如果你的业务逻辑中没有在本次调用中修改profileData或guildData,可以直接删掉最后两个set操作,不需要每次读取都重新写入,浪费请求配额还会增加不必要的写入延迟。
  • Node.js 12.16.1版本过旧,后续如果要升级discord.js v14+版本需要至少Node.js 16.9以上,有条件建议升级运行环境。

内容的提问来源于stack exchange,提问作者Antoine BASTIDE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:06:00