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.
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(),
);
},