![](/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.