Is it possible to do batched writes to add to existing fields? - firebase

My app has a for loop that writes data to my Firestore database.
However, right now, when I click my update button, Firestore updates the documents one by one, using transactions.
Thus, this results in me having to read every single document before being able to update it, which is extremely inefficient.
Is it possible for batched writes to perform an update feature similar to how transactions do?
For my case, the field I intend to update is a number, thus,
I am wondering if its possible to update the field by adding to it.
await transaction.update(stockListDocRef,
{'Num': outerStockListSnapshot.data['Num'] + Add});

You can use FieldValue.increment(x) to increment a field value in any sort of update operation, including batches.
See also: FieldValue.increment for Cloud Firestore in Flutter

Related

Can't understand Firestore batch update - Flutter

What I understand after reading the Firestore official batch operations doc is that, Batch operations perform multiple operations and can change multiple documents simultaneously.
However, when I read the sample code in the official firestore doc for updates it says:
var sfRef = db.collection("cities").doc("SF");
batch.update(sfRef, {"population": 1000000});
Now, I don't understand why they gave the name of a specific document when trying to update the batch. I thought the whole point of batch operations was to update multiple documents in a collection, so why are we giving the name of the document and limiting the operation only to a single document.
Thanks in advance :)
Now, I don't understand why they gave the name of a specific document when trying to update the batch.
It's required to call out each individual document to create, update, or remove in the batch. There are no alternatives to this. Firesotre doesn't offer any way to bulk update multiple items as a result of a query, similar to SQL "update where" queries. If you have multiple items to update in a batch, you would instead have to:
Perform the query to find each document
Iterate the results and collect references to each document
Add each document update to the batch using the batch API.

Updating 10 different fields of the same document in Firestore. Does the order matter?

I will run 10 updates on different fields of a single document in Firestore.
someDocRef.update({
[field_1]: "value1"
});
someDocRef.update({
[field_2]: "value2"
});
And so on...
What is really going to happen:
// PSEUDO CODE
1. An admin script will update 10 documents
2. A cloud function with a Firestore trigger will run 10 times
because of those 10 doc updates
3. On each run, that cloud function will fire an update for a
different field of the SAME DOCUMENT
QUESTION
The cloud function will run 10 times and update 10 different fields of the same object. I cannot be 100% in which order it will happen, right? Does the order of those 10 updates matter? I know it would matter if the update were to be done to the same field, but in this situation, each update will be on a different field. Do I need to make it as a transaction?
You can not be guaranteed an order of execution for any background Cloud Function trigger that happens in response to things that happen in other products, include Firestore document updates.
I can't determine for you if the order matters for your application - that's up to you to decide.
Consider instead performing all the changes in a single update. You don't need a transaction to update multiple fields in the same document. The API allows for you to update multiple fields with a single update. Transactions and batch writes are used when you want to affect multiple documents at the same time.

Do Firestore Function Triggers count as reads?

I know what you are probably thinking, "why does it matter? Don't try to over-complicate it just to optimize pricing". In my case, I need to.
I have a collection with millions of records in Firestore, and each document gets updated quite often. Every-time one gets updated, I need to do some data-cleaning (and more). So I have a function trigger by onUpdate that does that. In the function there's two parameters: document before update and document after update.
My question is:
Because the document is been passed as an argument, does that count as a database read?
The event generated by Cloud Firestore to send to Cloud Functions should not count as an extra read beyond what what was done by the client to initially trigger that event.

How to get documents that were updated in the last hour from firestore?

I am trying to implement full text search of firestore DB by using Elasticsearch.
In order to sync the firestore data to elasticsearch, I used cloud functions with Firestore update events, such that whenever a firestore document is updated, a cloud function is triggered which updates the elasticsearch.
This works as expected. However, this is not cost effective.
I would like to update the elasticsearch periodically every hour by querying the firestore DB for documents that changed in the last one hour and updating elasticsearch.
Is there a way to query firestore for only those documents that got updated in the last hour?
You will need to have a field in the database that reflects when the document was last updated. Without that, you can't build a query to get what you want.
I know this is an old question but in order to achieve this you could add a field to your documents in firestore like "indexed": boolean and run a cron on cloud functions that query docs with indexed == false and then after indexing change them to true.

Best way to trigger function when data is being read. Google Cloud Functions

I am trying to figure out the best way to execute my cloud function for my firestore database, when data is being read.
I have a field on all of my documents with the timestamp of when the document was last used, this is used to delete documents that haven't been used in two days. The deletion is done by another cloud function.
I want to update this field, when the documents is being used AKA read from my db. What would be the best way to do this?
onWrite(), onCreate(), onUpdate() and onDelete() is not an option.
My database is used by a Android App written in Kotlin.
There are no triggers for reading data. That would not be scalable to provide. If you require a last read time, you will have to control access to your database via some middleware component that you write, and have all readers query that instead. It will be responsible for writing the last read time back to the database.
Bear in mind that Firestore documents can only be written about once every second, so if you have a lot of access to a document, you may lose data.

Resources