Я работаю над приложением для обмена мгновенными сообщениями, и мне нужно, чтобы пользователь отправлял и получал сообщения в режиме реального времени. Я использую Firebase в качестве серверной части приложения, пакет flutter_bloc
для управления состояниями и потоки для отправки и получения сообщений в режиме реального времени.
Я успешно реализовал функцию отправки сообщений и могу получитьсообщения успешно из Cloud Firestore, но когда пользователь отправляет сообщение, оно не загружается в сообщения чата ListView
.
Это реализация метода ChatProvider
getCurrentChatMessages()
, который вызывается вChatBloc
.
Stream<List<ChatMessage>> getCurrentChatMessages() {
return this.messagesRef.orderBy('timestamp', descending: true)
.snapshots()
.map((QuerySnapshot snapshot) {
return snapshot.documents.map<ChatMessage>((DocumentSnapshot snapshot) => ChatMessage.fromFirestore(snapshot)).toList();
});
}
В ChatProvider
это методы, которые распространяют список сообщений чата на пользовательский интерфейс
Stream<ChatState> mapFetchCurrentChatMessagesEventToState(FetchCurrentChatMessagesEvent event) async* {
yield FetchingCurrentChatMessagesState();
final bool chatExists = await _chatProvider.chatExists;
// If chat does not exists create chat.
if (!chatExists) {
await _chatProvider.createChat();
}
_chatProvider.getCurrentChatMessages().listen((List<ChatMessage> chatMessages) {
print('Chat messages length: ${chatMessages.length}');
dispatch(FetchedCurrentChatMessagesEvent(chatMessages));
});
}
Stream<ChatState> mapFetchedCurrentChatMessagesEventToState(FetchedCurrentChatMessagesEvent event) async* {
final List<ChatMessage> chatMessages = event.chatMessages;
yield FetchedCurrentChatMessagesState(chatMessages);
}
Это ListView
, отображающийсообщения чата.
class ChatMessagesList extends StatefulWidget {
@override
_ChatMessagesListState createState() => _ChatMessagesListState();
}
class _ChatMessagesListState extends State<ChatMessagesList> {
List<ChatMessage> _chatMessages = List<ChatMessage>();
@override
Widget build(BuildContext context) {
return Expanded(
child: BlocBuilder<ChatBloc, ChatState>(
condition: (ChatState oldState, ChatState newState) => oldState.hashCode != newState.hashCode,
builder: (BuildContext context, ChatState state) {
if (state is FetchingCurrentChatMessagesState) {
return Center(
child: CircularProgressIndicator(),
);
}
if (state is FetchedCurrentChatMessagesState) {
_chatMessages = state.chatMessages;
}
if (_chatMessages.length == 0) {
return Container();
}
print('Chat Messages:\n$_chatMessages');
return ListView.builder(
reverse: true,
itemCount: _chatMessages.length,
itemBuilder: (BuildContext context, int index) {
final ChatMessage chatMessage = _chatMessages[index];
return ChatMessageTile(
chatMessage: chatMessage,
);
},
);
},
),
);
}
}
Всякий раз, когда отправляется сообщение, ChatBloc
отправляет обновленный список сообщений чата на виджет ChatMessagesList
, но виджет не обновляется соответствующим образом. Он отображает только первый элемент в списке _chatMessages
, пока я не pop
и push
маршрут, то есть когда я увижу обновленный список.
Я хочу список сообщений чатаобновляться отправленным сообщением, когда пользователь нажимает кнопку отправки сообщения.