0

I want to query certain data and update the query result in a batch.

If I use this format from this example,

let ref = db.collection("cities").whereField("sellerUserId", isEqualTo: userId)
db.runTransaction({ (transaction, errorPointer) -> Any? in
    let document: DocumentSnapshot
    do {
        try document = transaction.getDocument(ref) <-- error
    } catch let fetchError as NSError {
        errorPointer?.pointee = fetchError
        return nil
    }
    // more code
}) 

I get this error:

Cannot convert value of type "Query" to expected argument type "DocumentReference"

I get the same error with the batch writes:

let batch = db.batch()
let ref = db.collection("cities")
    .whereField("sellerUserId", isEqualTo: userId)
batch.updateData(["population": 1000000 ], forDocument: ref)

Is there any way to batch update the query result without iterating over individual document?

Kevvv
  • 3,655
  • 10
  • 44
  • 90
  • Can you explain *why* you want to do this? – Jay Jun 10 '21 at 20:05
  • @Jay I was trying to 1) do compound queries and 2) update the results in a batch instead of using the `for loop` to update the result individually. – Kevvv Jun 10 '21 at 20:55
  • While you can't do a query in a transaction - not sure why you would need to, you can definitely update multiple documents within a transaction, even using a for loop. It's not clear what exactly the issue is. The whole point of a transaction is being able to update a bunch of stuff at the same time and either have it all pass or all fail. – Jay Jun 11 '21 at 15:21

1 Answers1

1

As explained in this answer you are not able to use a query for a transaction. You indeed need to loop over the results yourself and run each transaction individualy.

The same is also with the batch updates. You would need to specify for each document the update you want to execute on it.

Tarik Huber
  • 7,061
  • 2
  • 12
  • 18
  • I think the gist of this answer is correct but for clarity, the whole point of a [transaction is being able to update multiple documents at the same time](https://firebase.google.com/docs/firestore/manage-data/transactions#transactions) and it either all passes or all fails. 'loop over' can certainly be done within a single transaction (we do that all the time) so it would not require individual transactions. e.g. if you want to update the status of 20 time stamps to today, that could easily be done within a single transaction by looping over the previously retrieved documents. – Jay Jun 11 '21 at 15:26
  • Sorry @Jay I tought this commend was about another question. There we talked about scaling counters using transactions. The point is quite similar but not so related to this one here. – Tarik Huber Jun 11 '21 at 22:03
  • lol. no worries. Sometimes these questions are very similar. – Jay Jun 11 '21 at 22:04
  • This was the question I touhght we are commenting on: https://stackoverflow.com/a/67928286/5519300 – Tarik Huber Jun 11 '21 at 22:07