Reputation: 437
I'm still new to Flutter and Firestore, and have a problem where I basically want to only populate a list with items in the collection "brites"
if (and only if) the documentID
also appear as a String
in an array in another Firestore collection called "users"
> "bookmarks"
> array
(containing Strings
with documentID:s).
I have a hard time knowing where to start, I believe mainly due to my currently vague understanding of Firestore and asynchronous streams and queries. Maybe where()
or map()
is the solution, but what that is concrete is over my head currently.
List<Widget> populateBriteList(AsyncSnapshot snapshot, int x, bool isBookmarksSection) {
List<Widget> list = new List<Widget>();
BriteShowItem _briteContent(j) {
return BriteShowItem(
briteID: snapshot.data.documents[j].documentID,
imagePath: snapshot.data.documents[j]["imagePath"],
title: snapshot.data.documents[j]["title"],
author: snapshot.data.documents[j]["author"],
published: snapshot.data.documents[j]["published"],
duration: snapshot.data.documents[j]["duration"],
isBookmarked: snapshot.data.documents[j]["isBookmarked"],
);
}
if (isBookmarksSection) {
for (int i=0; i<x; i++) {
//Here only list.add briteContent(i) if the "documentID" in passed in
//Snapshot ("brites" collection)
//is equal to a string in "bookmarks" array in "users" collection
list.add(
_briteContent(i)
);
}
} else {
for (int i=0; i<x; i++) {
list.add(
_briteContent(i)
);
}
}
return list;
}
Upvotes: 0
Views: 233
Reputation: 3371
So one thing is that when you are actually building the widgets that depend on some data in firestore, you ultimately already need to have that data. That doesn't mean you can't return a temporary value while you are waiting for a Future to resolve. But, in this case, it looks like you are calling this method once you already have the data. So maybe just pass the array of bookmarks in, also (that said, a method like this with a bunch of arguments is a good indicator that things are getting out of hand and some more structural changes are needed - for example, by splitting up the method depending on the conditions and calling different methods as needed):
List<Widget> populateBriteList(AsyncSnapshot snapshot, int x, bool isBookmarksSection, AsyncSnapshot bookmarkSnapshot) {
...
if (isBookmarksSection) {
for (int i=0; i<x; i++) {
if(bookmarkSnapshot.documents.where((document) => condition(document.data)).length > 0){
list.add(
_briteContent(i)
);
}
}
In this case, 'where(someTest)' is called on an iterable list, (documents), each element is passed into the someTest method, and if the result is true, that element is passed into the list. So if the list is greater than 0, at least one element satisfied that condition.
Upvotes: 1