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

为什么Firebase查询回调中返回的object类型数据,外部接收时为function类型?

问题原因
  • Firebase Realtime Database 的 on() 方法作用是注册持续的事件监听器,它的返回值本身就是后续用来移除该监听的函数,和你在回调函数内return的内容没有任何关系。
  • await 仅会对Promise类型的参数做等待处理,你给await传入的是on()返回的函数,非Promise类型的值被await修饰后会原样返回,因此userFromFirebase的类型就是function。
  • 你在child_added回调函数内的return值只会回传给on()方法的内部逻辑,根本不会向外传递给外层的userFromFirebase变量,且回调属于异步触发,你外层的console.log("userFromFirebase")执行时,回调大概率还未被触发。
解决方案

如果你只需要单次获取匹配的用户数据,不要用on()方法,改为使用返回Promise的once()方法,示例代码如下:

const fetchAllUsersData = async () => {
    setLoading(true);
    // 用once替代on,获取单次数据
    const snapshot = await firebase.database().ref("users").orderByChild("nickname").equalTo(nickname).once("child_added");
    const userFromFirebase = snapshot.val();
    console.log("userFromFirebase", typeof userFromFirebase); // 此时输出object
    setLoading(false);
}

fetchAllUsersData();

补充:如果你需要获取所有匹配nickname的用户数据,应该监听value事件:

const snapshot = await firebase.database().ref("users").orderByChild("nickname").equalTo(nickname).once("value");
const allUsers = [];
snapshot.forEach(childSnapshot => {
  allUsers.push(childSnapshot.val());
});
// allUsers就是所有匹配的用户数组

如果你确实需要持续监听child_added事件,就不能用await的方式获取回调返回的数据,直接在回调内部处理拿到的data即可:

const fetchAllUsersData = () => {
    setLoading(true);
    // 保存监听取消函数,后续需要取消监听时可以调用
    const unsubscribe = firebase.database().ref("users").orderByChild("nickname").equalTo(nickname).on("child_added", ((snapshot) => {
        const data = snapshot.val();
        console.log("data", typeof data); // object
        // 在这里直接处理拿到的data,比如存到state里
        setLoading(false);
    }));
    // 后续如果要停止监听,调用unsubscribe()即可
}

fetchAllUsersData();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:06:04