Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do a bulk update in Firestore

I'm using Cloud Firestore and have a collection of documents. For each document in the collection I would like to update one of the fields.

Using a transaction to perform the update would be inefficient because I do not need to read any of the data while updating it.

Batch updates seem like the right direction, however the docs do not include examples of updating multiple docs at once. See here: Batched Writes

like image 824
Trey Granderson Avatar asked Oct 20 '17 12:10

Trey Granderson


People also ask

How do I update my firestore collection?

Firestore Update Entire DocumentgetDatabase() → where we want to update a document. doc() → where we'll be passing references of database, collection and ID of a document that we want to update. setDoc() → where we actually pass new data that we want to replace along with the doc() method.

What is firestore batch?

There are two types of atomic operations in Cloud Firestore: Transactions: a transaction is a set of read and write operations on one or more documents. Batched Writes: a batched write is a set of write operations on one or more documents.

Can you upload CSV to firestore?

Step 1: Import CSV file and select fields You can create a table for existing Firestore collection or create database collection right from the Rowy UI. Then CSV import using the import data icon. For brand new collections, with import data you can create the table structure as well with ease.


2 Answers

If you have used Firebase database, writing to completely single separate locations atomically was not possible, that's why you would have to use batch writes, which means that either all of the operations succeed, or none of them are applied.

Regarding Firestore, all operations are now atomically processed. However, you can execute multiple write operations as a single batch that contains any combination of set(), update(), or delete() operations. A batch of writes completes atomically and can write to multiple documents.

This a simple example regarding a batch operation for write, update and delete operation.

WriteBatch batch = db.batch();

DocumentReference johnRef = db.collection("users").document("John");
batch.set(johnRef, new User());

DocumentReference maryRef = db.collection("users").document("Mary");
batch.update(maryRef, "Anna", 20); //Update name and age

DocumentReference alexRef = db.collection("users").document("Alex");
batch.delete(alexRef);

batch.commit().addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
        // ...
    }
});

Calling commit() method on the batch object means that you commit the entire batch.

like image 83
Alex Mamo Avatar answered Sep 21 '22 11:09

Alex Mamo


I was looking for a solution, found none, so I made this one, if anyone's interested.

public boolean bulkUpdate() {
  try {
    // see https://firebase.google.com/docs/firestore/quotas#writes_and_transactions
    int writeBatchLimit = 500;
    int totalUpdates = 0;

    while (totalUpdates % writeBatchLimit == 0) {
      WriteBatch writeBatch = this.firestoreDB.batch();

      List<QueryDocumentSnapshot> documentsInBatch =
          this.firestoreDB.collection("animals")
              .whereEqualTo("species", "cat")
              .limit(writeBatchLimit)
              .get()
              .get()
              .getDocuments();

      if (documentsInBatch.isEmpty()) {
        break;
      }

      documentsInBatch.forEach(
          document -> writeBatch.update(document.getReference(), "hasTail", true));

      writeBatch.commit().get();

      totalUpdates += documentsInBatch.size();
    }

    System.out.println("Number of updates: " + totalUpdates);

  } catch (Exception e) {
    return false;
  }
  return true;
}
like image 31
Jordi Reinsma Avatar answered Sep 22 '22 11:09

Jordi Reinsma