skip to Main Content

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.

enter image description here
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


  1. Chosen as BEST ANSWER

    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.

      async createSub() {
          this.isLoading = true;
          const db = getFirestore();
          const collectionRef = collection(
            db,
            "Subscribed",
            firebaseAuth.currentUser.uid,
            "checkout_sessions"
          );
          const collectionRef2 = collection(
            db,
            "Subscribed",
            firebaseAuth.currentUser.uid,
            "payments"
          );
    
          const docRef = await addDoc(collectionRef, {
            mode: "payment",
            price: this.selectedPrice,
            success_url: window.location.href,
            cancel_url: window.location.href,
            
          });
    
          onSnapshot(docRef, (snap) => {
            const { error, url } = snap.data();
            if (error) {
              console.error(`An error occured: ${error.message}`);
              
              this.isLoading = false;
            }
    
            if (url) {
              window.location.assign(url);
              addDoc(collectionRef2, {
              product:"prod_QIRNX4klvLTfKe",
              })
    
            }
           
          });
        },
      },
    };
    

    So now the code I had shown before works and it is able to find the product id and then display what I want. enter image description here


  2. 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 the items 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search