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

Firebase v9模块化开发报错:Expected type 'Ea', but it was: a custom Na object

解决Firebase v9监听订单数据的错误问题

错误原因分析

你的v9代码存在几个关键问题,导致了FirebaseError: Expected type 'Ea', but it was: a custom Na object错误:

  • 集合/文档引用构建错误:原教程逻辑是users集合→用户文档→orders子集合,但你用getDocs(db, "users", user?.id)的写法完全错误,不符合v9模块化的引用构建规则。
  • onSnapshot使用错误:onSnapshot是实时监听函数,不需要用await,它返回的是取消订阅的函数,而非Promise对象。
  • 数据处理逻辑顺序错误:你直接将原始快照赋值给orders再去map,不仅逻辑颠倒,而且快照本身不是数组,无法直接执行map操作。

修正后的v9代码

const [orders, setOrders] = useState([]);
useEffect(() => {
  let unsubscribe;
  
  if (user) {
    // 正确构建用户文档下的orders子集合引用
    const userDocRef = doc(db, "users", user.id);
    const ordersCollRef = collection(userDocRef, "orders");
    // 创建排序查询
    const orderedQuery = query(ordersCollRef, orderBy("created", "desc"));
    
    // 正确使用onSnapshot实时监听数据
    unsubscribe = onSnapshot(orderedQuery, (snapshot) => {
      // 格式化快照数据为需要的结构
      const formattedOrders = snapshot.docs.map(doc => ({
        id: doc.id,
        data: doc.data()
      }));
      setOrders(formattedOrders);
    });
  } else {
    setOrders([]);
  }

  // 组件卸载时取消监听,避免内存泄漏
  return () => {
    if (unsubscribe) unsubscribe();
  };
}, [user]);

关键修正点说明

  • 引用链对齐原教程逻辑:用doc(db, "users", user.id)获取用户文档引用,再用collection(userDocRef, "orders")获取该文档下的orders子集合,和非模块化的链式调用逻辑完全对应。
  • 规范onSnapshot用法:去掉多余的await,通过回调函数处理实时更新的快照,同时保存返回的取消订阅函数,在组件卸载时调用以防止内存泄漏。
  • 数据处理逻辑修正:在onSnapshot的回调里直接处理snapshot.docs的map转换,再将格式化后的数组传入setOrders,和原教程的数据处理逻辑保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:01:02