Flutter-How to use logical AND in firebase query and how to update data?

Viewed 887

I am new to flutter and looking for some sort of multiple where clauses or logical AND operator in my query, tried several things but none working for me. I am filtering users whose IDs match currently logged in user ID. Secondly there is a bool field status in firestore, I want to filter "status"==false as well. i.e

where userid=="currently logged in userid" && status==false

  Stream<QuerySnapshot> getData() async*{
    FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
    yield* Firestore.instance.collection('order').where("userid", isEqualTo: firebaseUser.email.toString()).snapshots();
  }

Secondly, I want to update this approve = false to approve = true on button press how can I do that? My IDE is showing a red line below that.

onPressed: () async {
       await db.collection('booking_tbl').document(doc.documentID).updateData('approve':true);
  },

Full piece of code is here:

  StreamBuilder<QuerySnapshot>(
      stream: db.collection('booking_tbl').snapshots(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return Column(
            children: snapshot.data.documents.map((doc) {
              return ListTile(
                    title: Text("Press the button to confirm booking"),
                    trailing: IconButton(
                      icon: Icon(Icons.verified_user),
                      color: Colors.green,
                      onPressed: () async {
                        await db.collection('booking_tbl').document(doc.documentID).updateData('approve':true);
                      },
                    ),
                ),
            }).toList(),
          );
        } else {
          return SizedBox();
        }
      }),
2 Answers

To preform and query, you have to do the following:

yield* Firestore.instance.collection('order').where("userid", isEqualTo: firebaseUser.email.toString()).where("status", isEqualTo: false).snapshots();

This will perform and query, meaning if a document contains this userid AND status is false then you will retrieve that document.


Regarding the error here:

onPressed: () async {
       await db.collection('booking_tbl').document(doc.documentID).updateData('approve':true);
  },

updateData() takes a map as an argument, so do the following:

onPressed: () async {
       await db.collection('booking_tbl').document(doc.documentID).updateData({'approve':true});
  },

You just stack the where clausel:

final QuerySnapshot snap = await Firestore.instance.collection("order")
    .where("userid", isEqualTo: "id")
    .where("status", isEqualTo: false)
    .where("email", isEqualTo: "email")
    .where("number", isGreaterThan: 3)
    .getDocuments();
final List<DocumentSnapshot> docs = snap.documents;

As stream:

Stream<QuerySnapshot> getData() async{
    FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
    return Firestore.instance.collection("order")
        .where("userid", isEqualTo: "id")
        .where("status", isEqualTo: false)
        .where("email", isEqualTo: "email")
        .where("number", isGreaterThan: 3)
        .snapshots();
}

Just be aware, that this does only take the currently logged in user, this will not update, when the user logs out and a new user logs in. The difference to your approach is, that i just map the streams, instead of specifying explicitly which elements to yield (and because i only map, the method does not need to be marked async*, only async, because i still have to await the call to get the currently logged in user).

The second question, should be in another question, but you need to give a Map as a parameter (wrap it in {}):

await db.collection('booking_tbl').document(doc.documentID).updateData({"approve":true});
Related