3
votes

I'm trying to create a cloud function to trigger every time a product on my project gets updated. Here is the idea.

I have 2 collections, stores and products.

Inside the stores collection, there is a sub-collection called products that contains all the products that the store sells. The data 'gets fed' by copying specific items from the main products root collection The idea is the my project gets a good performance as well as cost effective.

In order for this to work, I need to create a cloud function to be triggered every time a product gets modified and query all the stores that has that same product id and update the data.

I'm having a really hard time with that. Can anybody shine a light here for me? This is my cloud function.

// Exporting the function
export const onProductChange = functions.firestore
.document('products/{productId}')
// Call the update method
.onUpdate(async (snap, context) => {
    // Get the product ID
    const productID = context.params.productID;
    // Query for all the collections with the specific product ID.
    const resultSnapshot = await db.collectionGroup('products')
        .where('id', '==', productID).get();

    // Filter for the collections with the 'products' root and return an array.
    const snaphotsInStoreSubcollection = resultSnapshot.docs.filter(
        (snapshot: any) => {
            return snapshot.ref.parent === 'products';
    });

    const batch = db.batch();
    // Takes each product and update
    snaphotsInStoreSubcollection.forEach((el: any) => {
        batch.set(el.ref, snaphotsInStoreSubcollection.product);
    });
    await batch.commit();
});

error on cloud function console

Error: Value for argument "value" is not a valid query constraint. Cannot use "undefined" as a Firestore value. at Object.validateUserInput (/srv/node_modules/@google-cloud/firestore/build/src/serializer.js:273:15) at validateQueryValue (/srv/node_modules/@google-cloud/firestore/build/src/reference.js:1844:18) at Query.where (/srv/node_modules/@google-cloud/firestore/build/src/reference.js:956:9) at exports.onProductChange.functions.firestore.document.onUpdate (/srv/lib/product-update.js:29:10) at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:131:23) at /worker/worker.js:825:24 at at process._tickDomainCallback (internal/process/next_tick.js:229:7)

2
What exactly is not working? - Constantin Beer
onWrite might be preferred if users can add new products and they also need to be copied. Also, you should be returning your batch.commit(). More info is needed on the errors. Also, what does it say in your 'functions' log? - Flignats
Hey guys sorry about that. i've added the error log. - MrRobot

2 Answers

0
votes

I would suggest you take a look at this documentation and specially in Event Triggers.

Let me know if this helps.

0
votes

I think the snapshotsInStoreSubcollection.product is undefined

batch.set(el.ref, snaphotsInStoreSubcollection.product);

A snapshot is a document and its data is snapshot.data()

You cannot set undefined as a value in firestore and you are attempting to