I'm trying to create a user feed, just like that of twitter using Firebase & GetX.
In the code snippet is my function..
List<PostModel> postListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map((doc) {
return PostModel(
id: doc.id,
text: (doc.data() as dynamic)["text"] ?? "",
creator: (doc.data() as dynamic)["creator"] ?? "",
timestamp: (doc.data() as dynamic)["timestamp"] ?? 0,
);
}).toList();
}
Future<List<PostModel>> getFeed() async {
List<String> usersFollowing = await UserService() //['uid1', 'uid2']
.getUserFollowing(FirebaseAuth.instance.currentUser!.uid);
QuerySnapshot querySnapshot = await FirebaseFirestore.instance.collection("posts").where('creator', whereIn: usersFollowing)
.orderBy('timestamp', descending: true)
.get();
return postListFromSnapshot(querySnapshot);
}
What I want to do is to display the Future function getFeed(), I'm using GetX for state management. So, my problem is how can I display the result of this function using a ListView.Builder()
Here's how I used the Future builder
FutureBuilder(
future: _.listPost,
initialData: [PostModel(id: "2", creator: "Fm", text: "Testing", timestamp: Timestamp.now())],
builder: (BuildContext context, AsyncSnapshot snapshot){
if(snapshot.hasData == null){
return Text("Data is available");
} else{
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.toString().length,
itemBuilder: (context, index){
PostModel posts = snapshot.data[index];
return Column(
children: [
Text(posts.text)
],
);
},
);
}
},
)
And here's the error I got
The following NoSuchMethodError was thrown building:
The method '[]' was called on null.
Receiver: null
Tried calling: [](3)
It also pointed to an error on the
PostModel post line.. the [index] to be precise
CodePudding user response:
First, make your AsyncSnapshot snapshot
an AsyncSnapshot<List<PostModel>> snapshot
. That is not your primary problem, but it will make things a lot easier to have proper typing and not have to guess around using dynamic
.
Your problem is that hasData
is a bool
. It is either true
or false
, but never null
. I wonder how you got that line past your compiler. Are you using an outdated version of Flutter? You should check this, your compiler is your friend, if it isn't helping you properly, this will be a hard and rocky road.
Anyway, you should check whether there is data, if there is none, you are still waiting:
FutureBuilder(
future: _.listPost,
builder: (BuildContext context, AsyncSnapshot<List<PostModel>> snapshot){
if(!snapshot.hasData){
return CircularProgressIndicator();
} else {
final postList = snapShot.requireData;
return ListView.builder(
shrinkWrap: true,
itemCount: postList .length,
itemBuilder: (context, index){
final post = postList[index];
return Column(
children: [
Text(post.text)
],
);
},
);
}
},
)