fluttergoogle-cloud-firestore

Flutter user filters in Firebase database streaming


I'm streaming from FirebaseFirestore, where a user has two options for filtering the data.

I have created a method for that logic, but I don't know which object data my method should take and as such I can't get the itemCount when I want to use the ListView.builder.

In my code, I've done the initialization as follows:

late String? selectedStatus;
 late List<String> status;
 late String? selectedOrder;
 late List<String> nameOrder;
 int selectedStatusIndex = -1;
 int selectedNameOrder = -1;

@override
  void initState() {
    super.initState();
    status = [
      "Not Verified",
      "Pending verification",
      "Verified",
    ];
    selectedStatus = status[0];

    nameOrder = [
      "First Name",
      "Last Name",
    ];
    selectedOrder = nameOrder[0];
  }

String fieldName() {
    if (selectedOrder == nameOrder[1]) {
      return "FirstName";
    }
    if (selectedOrder == nameOrder[2]) {
      return "LastName";
    } else {
      return "";
    }
  }

Then in my method:

filter() {
    if (selectedStatus == status[0]) {
      if (selectedOrder == nameOrder[0]) {
        return FirebaseFirestore.instance
            .collection("collectionPath")
            .snapshots();
      } else {
        return FirebaseFirestore.instance
            .collection("collectionPath")
            .orderBy(
              fieldName(),
              descending: false,
            )
            .snapshots();
      }
    } else {
      if (selectedOrder == nameOrder[0]) {
        return FirebaseFirestore.instance
            .collection("collectionPath")
            .where("Status", isEqualTo: selectedStatus)
            .snapshots();
      } else {
        return FirebaseFirestore.instance
            .collection("collectionPath")
            .where("Status", isEqualTo: selectedStatus)
            .orderBy(
              fieldName(),
              descending: false,
            )
            .snapshots();
      }
    }
  }

In my build widget, I have a stream build where I called my filter() method in the stream.

StreamBuilder(
  stream: filter(),
  builder: (context, snapshot){
  return ListView.Builder(
      itemCount: //This is where the problem is 
      itemBuilder: .....
     )
   )

The problem is in the itemCount. I believe since my filter() does not take in any object, the stream builder does not understand it as a query from Firestore. But the problem is I don't which object FirebaseFirestore, and for that matter my filter() method should take.


Solution

  • Since you're using a StreamBuilder, so there's no need to nest a ListView.Builder in there. Instead use the normal ListView constructor with the children you get from the snapshots() stream.

    Following the Flutter example from the Firebase documentation on listening to updates:

    StreamBuilder<QuerySnapshot>(
      stream: filter(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return const Text('Something went wrong');
        }
    
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Text("Loading");
        }
    
        return ListView(
          children: snapshot.data!.docs
              .map((DocumentSnapshot document) {
                Map<String, dynamic> data =
                    document.data()! as Map<String, dynamic>;
                return ListTile( // Render your document data here
                  title: Text(data['full_name']),
                  subtitle: Text(data['company']),
                );
              })
              .toList()
              .cast(),
        );
      },