如何查询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
相关产品推荐
相关产品推荐

