Reputation: 258
I am trying to retrieve a whole collection in firestore
using StreamBuilder
but I got stuck in mapping the result according to my dart model
This is the dart model thread.dart:
class Thread {
final String threadTitle;
final String threadContent;
final String threadFlair;
final String threadTimestamp;
final List<String> threadLikedBy;
final List<String> originalPoster;
Thread({
this.threadTitle,
this.threadContent,
this.threadTimestamp,
this.threadFlair,
this.threadLikedBy,
this.originalPoster,
});
factory Thread.fromMap(Map<String, dynamic> map) => Thread(
threadTitle: map["threadTitle"],
threadContent: map["threadContent"],
threadFlair: map["threadFlair"],
threadTimestamp: map["threadTimestamp"],
threadLikedBy: List<String>.from(map["threadLikedBy"].map((x) => x)),
originalPoster: List<String>.from(map["originalPoster"].map((x) => x)),
);
Map<String, dynamic> toMap() => {
"threadTitle": threadTitle,
"threadContent": threadContent,
"threadFlair": threadFlair,
"threadTimestamp": threadTimestamp,
"threadLikedBy": List<dynamic>.from(threadLikedBy.map((x) => x)),
"originalPoster": List<dynamic>.from(originalPoster.map((x) => x)),
};
}
This is the widget where I display the results in a listview:
class _ThreadsBodyState extends State<ThreadsBody> {
final threads = _mThreadService.retriveData(path: "posts", builder: (data) => Thread.fromMap(data));
@override
Widget build(BuildContext context) {
return Container(
child: StreamBuilder<Object>(
stream: threads,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
Thread thrd = (snapshot.data as List)[index];
return ThreadCard(thread: thrd,);
},
);
} else {return Text('no data');}
}),
);
}
}
and here's posts_service.dart where I have the Stream function
//After restructuring my model and adding:
//List<String> threadLikedBy; and List<String> originalPoster;
//this method works no more
Stream<List<T>> retrieveData<T>({
@required String path,
@required T builder(Map<String, dynamic> data),
}) {
final reference = firestoreInstance.collection(path);
final snapshots = reference.snapshots();
return snapshots.map((snapshot) => snapshot.docs.map((snapshot) => builder(snapshot.data())).toList());
}
It appears to be that I am messing up the mapping in the return but I can't exactly figure out how to fix it.
Upvotes: 1
Views: 782
Reputation: 3563
in your 'posts_services.dart' add the following function:
Future<QuerySnapshot> fetchThreads() async {
return await firestoreInstance.collection('posts').get();
}
Now in your widget where you build your ListView
should look like this:
class _ThreadsBodyState extends State<ThreadsBody> {
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder<QuerySnapshot>(
future: youService.fetchThreads(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.size, //to retrieve the size
itemBuilder: (BuildContext context, int index) {
Thread thrd = Thread.fromMap(snapshot.data.docs[index].data());
return ThreadCard(thread: thrd,);
},
);
} else {return Text('no data');}
}),
);
}
}
Upvotes: 2