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

如何查询Firestore中文档嵌套集合中的产品ID?

问题描述

需要在Vue的v-if语句中判断用户是否已购买指定产品,需查询Firestore中Subscribed/{用户UID}/payments/{自动生成文档ID}下嵌套的items/price/product字段是否匹配目标产品ID(prod_QIRNX4klvLTfKe)。尝试过普通查询和collectionGroup查询均未成功。

尝试过的代码

普通查询代码

<script>
import { projectFirestore } from '../../Firebase/Config'
import PriceSelection1 from "./CowgirlVid/PriceSelection1.vue";
import SubscribedAccountSignup1 from "./CowgirlVid/SubscribedAccountSighnup1.vue";
import { firebaseAuth } from "../../Firebase/firebase";
import { ref } from 'vue'
import {
  getFirestore,
  collection,
  query,
  where,
  getDocs,
} from "firebase/firestore";
export default {
    components: {
    PriceSelection1,
    SubscribedAccountSignup1
  },
  data() {
    return {
      isLoading: false,
      Purchased2: null,
    };
  },

  mounted() {
    this.fetchSubscription();
  },

  methods: {
    async fetchSubscription() {
      this.isLoading = true;
      const db = getFirestore();
      const subsRef = collection(
        db,
        "Subscribed", firebaseAuth.currentUser.uid, "payments"
      );
      const subsQuery = query(
        subsRef, 
        where("product", "==", "prod_QIRNX4klvLTfKe" )
      );

      this.subscription = await getDocs(subsQuery)
        .then((sub) => 
            sub.docs.length > 0 ? sub.docs[0].data() : null);

      this.isLoading = false;
    },
  },
</script>

Collection Group查询代码

methods: {
    async fetchSubscription() {
      this.isLoading = true;
      const db = getFirestore();
      const subsRef = collection(
        db,
        "Subscribed", firebaseAuth.currentUser.uid, "payments"
      );
      const subsQuery = query(collectionGroup(
        subsRef, "items", "price" ),
        where("product", "==", "prod_QIRNX4klvLTfKe" )
      );

      this.subscription = await getDocs(subsQuery)
        .then((sub) => 
            sub.docs.length > 0 ? sub.docs[0].data() : null);

      this.isLoading = false;
    },
  },

注:此处的subscription指Stripe一次性产品,而非订阅产品。

解决方案

方法1:修正普通查询的嵌套字段路径

普通查询失败的核心原因是:product字段并非直接存在于payments文档的根层级,而是嵌套在items.price结构下,需要用点路径来精准定位嵌套字段。同时建议直接维护Purchased2布尔值,更适合v-if判断:

async fetchSubscription() {
  this.isLoading = true;
  const db = getFirestore();
  const subsRef = collection(
    db,
    "Subscribed", firebaseAuth.currentUser.uid, "payments"
  );
  // 使用点路径定位嵌套的product字段
  const subsQuery = query(
    subsRef, 
    where("items.price.product", "==", "prod_QIRNX4klvLTfKe" )
  );

  const querySnapshot = await getDocs(subsQuery);
  // 直接将结果转为布尔值,便于v-if判断
  this.Purchased2 = !querySnapshot.empty;
  this.isLoading = false;
}

如果items是数组类型(每个支付文档包含多个商品条目),上述查询会自动匹配数组中至少有一个条目满足price.product == 指定ID的文档,完全符合“用户是否购买过该产品”的判断需求。

方法2:正确使用Collection Group查询(不推荐)

如果一定要用collectionGroup,注意它是针对所有同名集合的全局查询,不需要基于特定用户的集合引用。需要先在Firebase控制台为payments集合创建集合组索引,然后按以下方式编写:

async fetchSubscription() {
  this.isLoading = true;
  const db = getFirestore();
  // 直接创建payments集合组的查询
  const subsQuery = query(
    collectionGroup(db, "payments"),
    where("items.price.product", "==", "prod_QIRNX4klvLTfKe"),
    // 额外限定当前用户,避免查询其他用户数据
    where("__name__", "==", firebaseAuth.currentUser.uid)
  );

  const querySnapshot = await getDocs(subsQuery);
  this.Purchased2 = !querySnapshot.empty;
  this.isLoading = false;
}

这种方法需要额外配置索引,且查询范围更大,效率不如方法1,优先推荐方法1。

在Vue模板中使用判断

模板中直接通过v-if判断:

<template>
  <div v-if="isLoading">加载中...</div>
  <PriceSelection1 v-else-if="!Purchased2" />
  <SubscribedAccountSignup1 v-else />
</template>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:14:56