How to solve: Flutter Firestore Update Where

Question

Asked by Martin on January 03, 2022 (source).

I'm trying to run a query that retrieves a single row given a where clause and updates it. I understand that Firebase doesn't support an UpdateWhere operations so I'm trying to use a Transaction instead.

I'm having difficulty making it work, maybe I'm too used to sql dbs... Here's my broken code

try {
    final whereQuery = _db
        .doc(userPath(user))
        .collection("someInnerCollection")
        .where("active", isEqualTo: true)
        .limit(1);

    await _db.runTransaction((transaction) async {
        final entry = await transaction.get(whereQuery);  // This doesn't compile as .get doesn't take in a query
        await transaction.update(entry, {
            "someValue": "newValue",
        });
    });
} catch (e) {
    ...
}

Answer

Question answered by Rogelio M (source).

From the test I’ve made, I would suggest the following to achieve what you mention:

Based on the following answer:

As you can see from the API documentation, where() returns a Query object. It's not a DocumentReference.

Even if you think that a query will only return one document, you still have to write code to deal with the fact that it could return zero or more documents in a QuerySnapshot object. I suggest reviewing the documentation on queries to see examples.

After doing the query consult, you have to get the DocumentReference for that given result.

Then, you can use that reference to update the field inside a Batched writes

try {
    final post = await firestore
        .collection('someInnerCollection')
        .where('active', isEqualTo: true)
        .limit(1)
        .get()
        .then((QuerySnapshot snapshot) {
            //Here we get the document reference and return to the post variable.
            return snapshot.docs[0].reference;
        });

    var batch = firestore.batch();
    //Updates the field value, using post as document reference
    batch.update(post, { 'someValue': 'newValue' }); 
    batch.commit();
    
} catch (e) {
    print(e);
}
FIREBASE FLUTTER GOOGLE-CLOUD-FIRESTORE
SHARE: