Reputation: 161
I have a home_page.dart
file whose body has a StreamBuilder
it recieves the stream from my getChats()
function. In the StreamBuilder
's builder function I sort the all the documents after storing them in a list named docsList
based on the lastMessageTime
field so that the document with the latest message is at the top (first).
As the ListView
is using the docsList
for building the cards it is expected that the document which has the most resent message should be displayed first. Which only happens when the list is build for the first time. After that if I send a new message to the chat which is not at the top this happens:
Initially:
When I send a message which the text 'test' to the chat "Heah Roger" this is how the list gets updated:
As it can be seen the Time on the right and the subtext changes for the first tile but the image and name didn't (same for second tile). Even though the documents are updated in the docsList
and are sorted in the desired manner (I printed it to check it). Somehow the photo and the name alone are not being updated in the UI alone.
Note: The correct fields are updated in the firestore. Also if I restart the app after killing it. It shows the desired result:
getChats()
Stream<QuerySnapshot<Map<String, dynamic>>> getChats(User currentUser) {
return FirebaseFirestore.instance
.collection('chats')
.where('users', arrayContains: currentUser.id)
.snapshots();
}
home_page.dart
body: StreamBuilder(
stream: RepositoryProvider.of<FirestoreRepository>(context).getChats(BlocProvider.of<AuthenticationBloc>(context).state.user),
builder: (context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData && snapshot.data.docs.length > 0) {
List docsList = snapshot.data.docs;
docsList.sort((a, b) => b.data()['lastMessageTime'].compareTo(a.data()['lastMessageTime']));
return ListView.builder(
itemCount: docsList.length,
itemBuilder: (context, index) {
return SingleChatCard(chatRoom: ChatRoomModel.fromMap(docsList[index].data()));
},
);
} else {
return ...
}
},
),
Can anyone help me figure out the underlying problem that is causing this weird behavior?
Upvotes: 1
Views: 552
Reputation: 330
Looks like an key issue to me, When you're using your custom Widget to render in a listview, with some complicate data flow, Flutter react to these changes one level at a time: You can refer: https://www.youtube.com/watch?v=kn0EOS-ZiIc
In your example, you can do something like this:
return SingleChatCard(
key: ValueKey(index),
chatRoom: ChatRoomModel.fromMap(docsList[index].data()));
},
Upvotes: 1