How to add firebase trigger for any document update? - firebase

As described in firebase cloud functions documentation a trigger must always point to a document. But I want to create a trigger when any document is updated. Assume I don't know which document is updated, how I can add a trigger not knowing the document id?

Firebase cloud functions offers you the onUpdate() trigger. Just look at this post from the docs.
EDIT
This is a code example from the firebase docs. For more information look here.
exports.updateUser = functions.firestore
.document('users/{userId}')
.onUpdate((change, context) => {
// Get an object representing the document
// e.g. {'name': 'Marie', 'age': 66}
const newValue = change.after.data();
// ...or the previous value before this update
const previousValue = change.before.data();
// access a particular field as you would any JS property
const name = newValue.name;
// perform desired operations ...
});index.js

Related

Is there any way of knowing if a document has been added to a collection in firebase using firebase functions

Basically the question again:
Suppose there is a collection called 'People'.
Firestore functions can detect changes to a particular document, but is there anyway of knowing when a document(say 'Person1') is added to the collection using firebase functions?
If not, is there any alternate way to get to know when a document is added?
There is a specific function type that only triggers when a document gets created. From the documentation comes this example of how to use it:
exports.createUser = functions.firestore
.document('users/{userId}')
.onCreate((snap, context) => {
// Get an object representing the document
// e.g. {'name': 'Marie', 'age': 66}
const newValue = snap.data();
// access a particular field as you would any JS property
const name = newValue.name;
// perform desired operations ...
});

Cloud Functions Update Sub-collections

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)
I would suggest you take a look at this documentation and specially in Event Triggers.
Let me know if this helps.
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

how do I get the dataID when using cloud firestore triggers function?

I have an Event Collection in the Firestore database like this:
I want to use cloud firestore triggers. when a user attends an event, the capacity of the event will be -1, and when this field is updated I want to automatically update another field ("rankPoint") +3
to implement this, I need to Trigger a function when a document is updated
from firestore documentation, it will be like this
exports.updateUser = functions.firestore
.document('users/{userId}')
.onUpdate((change, context) => {
// Get an object representing the document
// e.g. {'name': 'Marie', 'age': 66}
const newValue = change.after.data();
// ...or the previous value before this update
const previousValue = change.before.data();
// access a particular field as you would any JS property
const name = newValue.name;
// perform desired operations ...
});
for my case, it should be 'events/{eventId}' right? but how do I get that eventID in the wildcard? does it come from client side? I mean in iOS/Android I will write the code to update like
db.collection("eventss").document("someEventIDHere").setData(data)
is it from the client?
Your function will only be delivered the document that matched your function's pattern (users/{userId}) that was changed. Other documents are not available until you query for them. So, if you want a document from you events collection, you will have to write some code to access it, then decide what to do from there.
It sounds like you're expecting there to be an eventId wildcard, but there is not. There is just the userId wildcard that you defined in your function. Other values will need to be derived from the data you have available in your user document.

how to access a document from Main Collection after triggering onCreate cloud function on subcollection document?

so let say I have photos collection like this:
and the subcollection (likers) like this:
I want to make a trigger, If a new likers document is created, then I want to increase point field +=1 in the main Collection document ( q27yiVv4g7XVgiaG7c7a). how to get access to that q27yiVv4g7XVgiaG7c7a document so I can increase the point?
should be use the code below, but I don't know how to access that document
exports.createUser = functions.firestore
.document('photos/{photoId}/likers/{likersId}')
.onCreate((snap, context) => {
});
You can build a reference to the document using the wildcard photoId that you defined in your function along with the ref of the changed document in the snapshot:
const photoId = context.params.photoId
const photoRef = snap.ref.firestore.collection('photos').doc(photoId)

Firestore Realtime Listener equivalent of "Child_Added"

I am trying to figure out a solution for the Firestore realtime listeners. I know you can listen to changes and in onSnapshot see what was added, removed, changed.. but is there a way to just listen to additions?
I don't like how anytime there is a change in data, or a new document is added, the query retrieves every single piece of data.. Feels like unnescary data transfer.. especially if you were using the application on a 3G Network
Is that a legitimate concern? or is the query returning negligible data? I just want to get the "new" additions to the collection
Have you tried this?
exports.createUser = functions.firestore
.document('users/{userId}')
.onCreate((snap, context) => {
// Get an object representing the document
// e.g. {'name': 'Marie', 'age': 66}
const newValue = snap.data();
// access a particular field as you would any JS property
const name = newValue.name;
// perform desired operations ...
});

Resources