I am trying to run a query to see if a user’s document contains a product ID inside of the document but the problem is that the product ID is stored within its own dropdown collection and not in the first data group, so what I need to do is reach down but the problem is that there can be more than one product like this that all have autogenerating id’s when they are created. I am trying to query this to make sure the user has purchased the product before displaying content on it in a v-if statement in vue.
As you can see there are multiple documents within the payments collection and the product I am after is first under items and then under price before I can get there, ordinarily I would just navigate right down to the product but I can’t since the payments collection documents autogenerate and have autogenerating ids.
What I have tried doing is this below.
<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;
},
},
Ignore the subscription it doesn’t mean a subscription we are dealing with stripe one time products that I am trying to get the id off I know that subscription products have the id on the top level but these are unfortunately one time products which do not.
I have also tried using collectionGroup queries from the firebase docs like below
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;
},
},
Yes, I have imported collectionGroup I just haven’t included the top of my code in this snippet as it hasn’t changed.
Does anyone have any idea how to get the product id by using collectionGroup or some other means? I would greatly appreciate any help.
2
Answers
Thank you for the advice about creating a new array with the products in, I have now added this on the price selection page which takes me to the stripe checkout and I have added a line at the end when the success Url gets attached it adds the product to the product array.
So now the code I had shown before works and it is able to find the product id and then display what I want.
As far as I can see in your screenshot, the
items
field is a type array field containing complex objects. Unfortunately, there is no way you can get documents from the "payments" collections based only on a single ID field of an object that exists inside theitems
array. In other words, you cannot create a query based only on the product ID. To be able to filter the data, you should use the entire object, and not only some partial data. The object should contain values for all the fields.If you cannot use the entire object to create the filtering, then the only option that you have is to create an array that can hold only the IDs of the products. In the end, you can filter the documents in the collection, using the
array contains
operator.