Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Firestore update multiple documents matching a condition, using one query?

In other words, I'm trying to figure out what is the Firestore equivalent to this in SQL:

UPDATE table SET field = 'foo' WHERE <condition>` 

Yes, I am asking how to update multiple documents, at once, but unlike the linked questions, I'm specifically asking how to do this in one shot, without reading anything into memory, because there's no need to do so when all you want is to set a flag on all documents matching a condition.

db.collection('table')   .where(...condition...)   .update({     field: 'foo',   }); 

is what I expected to work, CollectionReference doesn't have an .update method.

The Transactions and Batched Writes documentation mentions transactions and batched writes. Transactions are out because "A transaction consists of any number of get() operations followed by any number of write operations" Batched writes are also not a solution because they work document-by-document.

With MongoDB, this would be

db.table.update(   { /* where clause */ },   { $set: { field: 'foo' } } ) 

So, can Firestore update multiple documents with one query, the way SQL database or MongoDB work, i.e. without requiring a round-trip to the client for each document? If not, how can this be done efficiently?

like image 870
Dan Dascalescu Avatar asked Feb 23 '18 12:02

Dan Dascalescu


People also ask

How do I get most recent documents on firestore?

Is there any way to get the last created document in Firebase Firestore collection? Yes, there is! The simplest way to achieve this is to add a date property to each object in your collection, then simply query it according to this new property descending and call limit(1) function. That's it!

Is there any way to update a specific index from the array in firestore?

Is there any way to update a specific index from the array in Firestore? No, there is not! This is not possible because if you want to perform an update, you need to know the index of that particular element. When talking about Cloud Firestore arrays, the things are different that you might think.


2 Answers

Updating a document in Cloud Firestore requires knowings its ID. Cloud Firestore does not support the equivalent of SQL's update queries.

You will always have to do this in two steps:

  1. Run a query with your conditions to determine the document IDs
  2. Update the documents with individual updates, or with one or more batched writes.

Note that you only need the document ID from step 1. So you could run a query that only returns the IDs. This is not possible in the client-side SDKs, but can be done through the REST API and Admin SDKs as shown here: How to get a list of document IDs in a collection Cloud Firestore?

like image 106
Frank van Puffelen Avatar answered Sep 22 '22 08:09

Frank van Puffelen


Frank's answer is actually a great one and does solve the issue.

But for those in a hurry maybe this snippet might help you:

const updateAllFromCollection = async (collectionName) => {     const firebase = require('firebase-admin')      const collection = firebase.firestore().collection(collectionName)      const newDocumentBody = {         message: 'hello world'     }      collection.where('message', '==', 'goodbye world').get().then(response => {         let batch = firebase.firestore().batch()         response.docs.forEach((doc) => {             const docRef = firebase.firestore().collection(collectionName).doc(doc.id)             batch.update(docRef, newDocumentBody)         })         batch.commit().then(() => {             console.log(`updated all documents inside ${collectionName}`)         })     }) } 

Just change what's inside the where function that queries the data and the newDocumentBody which is what's getting changed on every document.

Also don't forget to call the function with the collection's name.

like image 41
Renato Trombini Neto Avatar answered Sep 22 '22 08:09

Renato Trombini Neto