Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update multiple documents in a single transaction with dart and Firestore

I'm trying to create a save transaction with Flutter / Dart and Firestore which does the following:

  1. Add a new item with attribute "position: 1" to a collection of documents
  2. Increment the "position" attributes of all other documents in this collection with a position > 1 by 1 (++)

A single document looks like this:

{
    "title": "Some title",
    "position": 1
}

In the documentation (https://firebase.google.com/docs/firestore/manage-data/transactions) I found explanation on how to make a save transaction on a single document but not on how to create this "two-step-atomic-transaction" that I need to save insert and update in a collection.

Maybe anyone has a hint for me?

Update: Thanks for your input Frank. Here is a code snippet which hopefully explains what I want to achieve:

@override
Future addCatalogItem(CatalogItem catalogItem) {

 return firestore.runTransaction((Transaction transaction) async {

  // Update position (++) of existing catalogItems
  await firestore
      .collection(path)
      .where("catalogId", isEqualTo: catalogItem.catalogId)
      .snapshots()
      .forEach((snapshot) {
    snapshot.documents.forEach((document) {
      // document.reference.updateData({"position": document.data["position"]});
      transaction.update(document.reference, {"position": document.data["position"] + 1});
    });
  });

  // Add the new catalogItem at position 1
  await firestore
      .collection(path)
      .document(catalogItem.id)
      .setData(catalogItem.toJson());

});

}

like image 590
Michael Avatar asked Jan 14 '19 21:01

Michael


1 Answers

A transaction can't contain a query. So you will need to first run a query to find the matching documents, and then get-and-update each document within the transaction. Aside from that it should be fairly straightforward.

  1. Run a query to determine all affected documents
  2. Start a transaction
  3. Create the new document
  4. Loop over the affected documents and for each:

    1. Read the document from the transaction
    2. Update the document data
    3. Write the document back through the transaction

Give it a try, and if you get stuck, post back with the code that reproduces where you got stuck.

like image 130
Frank van Puffelen Avatar answered Oct 31 '22 01:10

Frank van Puffelen