为什么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
相关产品推荐
相关产品推荐

