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

如何运行嵌套Firestore查询?解决doc不是函数的类型错误

问题解决:Firestore查询优惠并判断用户使用状态

错误原因分析

  1. 变量名冲突:你在snapshot.forEach((doc) => {})里把参数命名为doc,这和Firebase提供的doc()函数重名了,导致回调内部调用的doc()其实是快照对象,不是创建文档引用的函数,所以抛出「doc is not a function」的错误。
  2. 异步操作未正确处理:getDoc()是异步函数,直接调用会返回Promise对象,无法直接调用exists()方法,必须用await等待它完成。

正确实现代码

import { doc, collection, query, where, getDocs, getDoc } from "firebase/firestore";

export const getOffers = async (id, uid) => {
  const offersRef = collection(FIREBASE_FIRESTORE, "venues", id, "offers");
  const q = query(offersRef, where("active", "==", true));
  const snapshot = await getDocs(q);

  // 用map生成包含异步操作的Promise数组,再用Promise.all等待全部完成
  const offersData = await Promise.all(
    snapshot.docs.map(async (docSnapshot) => {
      // 这里用docSnapshot作为参数名,避免和doc函数冲突
      const redemptionRef = doc(FIREBASE_FIRESTORE, "users", uid, "redemptions", docSnapshot.id);
      const redemptionSnapshot = await getDoc(redemptionRef);
      
      return {
        id: docSnapshot.id,
        exists: redemptionSnapshot.exists(),
        ...docSnapshot.data(),
      };
    })
  );

  return offersData;
};

关键修改点

  • 将forEach回调的参数名从doc改为docSnapshot,避免覆盖Firebase的doc()函数。
  • 使用map替代forEach生成Promise数组,配合Promise.all批量处理异步的getDoc请求,确保所有优惠的使用状态都查询完成后再返回结果。
  • 在getDoc前添加await,等待异步操作完成后再获取快照的exists()状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:34:58