![](/img/trans.png)
[英]How to properly unsubscribe to an onValue listener for Firebase Realtime Database
[英]onValue triggering multiple times
我使用的是 Node.js v18.12.1 和 Discord.js v14。 用于开发 Discord 机器人。 我需要从 Firebase 读取一些数据。 我很困惑,因为我已经习惯了 Java 与 Hibernate 获取数据的方式不同。 在这里,我需要使用onValue()
侦听器。
我的onValue()
行为很奇怪。 它不只是从 Firebase 读取数据,而是完全跳过,然后触发多次,每次都跳过其代码的主体块,然后它实际执行后面的代码。
我在这个论坛的某个地方读到,这可能会发生,因为有更多的onValue()
侦听器被订阅并且它们都被激活了。 有人提到我需要在onValue()
“之前”某处使用off()
函数。 这让我很困惑,因为我在很多地方都使用这个监听器。 我在每个命令文件中的execute(interaction)
函数中都需要它。 你知道,当你需要在 Discord 中执行斜杠命令时。 我有这样的东西:
async execute(interaction) {
const infographicRef = ref(db, '/infographics/arena/' + interaction.options.getString("arena-team"));
var imageUrl = null;
var postUrl = null;
onValue(infographicRef, (snapshot) => {
imageUrl = snapshot.child("image-url").val();
interaction.reply(imageUrl);
})
},
我计划在每个 command.js 文件中为每个命令设置onValue()
。 我不确定到底该怎么做。
此外,我尝试使用once()
方法解决此问题,我在 Firebase 文档中看到它,但我收到错误: ref.once() is not a function
。
似乎在未执行主体时首次触发 onValue 方法后,我在interactionCreate.js
中的代码也被触发,它指向要再次执行的命令:
const { Events } = require('discord.js');
module.exports = {
name: Events.InteractionCreate,
async execute(interaction) {
if (!interaction.isChatInputCommand()) return;
const command = interaction.client.commands.get(interaction.commandName);
if (!command) {
console.error(`No command matching ${interaction.commandName} was found.`);
return;
}
try {
await command.execute(interaction);
} catch (error) {
console.error(`Error executing ${interaction.commandName}`);
console.error(error);
}
},
};
我的bot.js
(在我的例子中是一个索引文件)
const fs = require('node:fs');
const path = require('node:path');
const { Client, Collection, Events, GatewayIntentBits } = require('discord.js');
const { token } = require('./config.json');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
const eventsPath = path.join(__dirname, 'events');
const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'));
for (const file of eventFiles) {
const filePath = path.join(eventsPath, file);
const event = require(filePath);
if (event.once) {
client.once(event.name, (...args) => event.execute(...args));
} else {
client.on(event.name, (...args) => event.execute(...args));
}
}
client.commands = new Collection();
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const filePath = path.join(commandsPath, file);
const command = require(filePath);
client.commands.set(command.data.name, command);
}
client.once(Events.ClientReady, () => {
console.log('Ready!');
});
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand()) return;
const command = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
}
});
client.login(token);
onValue
函数注册了一个实时侦听器,它继续监视数据库中的值。
如果你想读取一个值一次,可以使用 v9 中的get()
函数来完成(这相当于早期 SDK 版本中的once
方法)。 查看一次读取数据文档中的代码示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.