Как обновить состояние для всех пользователей в моем приложении чата Jetpack Compose при отправке сообщения?
Jetpack Compose. Проблема с обновлением состояния. Обновляется только у отправителя сообщения, но у других пользователей экран почему-то не обновляется. Я использую архитектуру MVI
В моей viewModel для экрана с чатом есть две функции, getMessages() срабатывает сразу при открытии чата в launchedEffect с ключом Unit, то есть всего один раз. В getMessages() потом запускается корутина, где я обновляю state. У каждого пользователя в этот момент экран обновляется, сообщения отображаются. Но, когда отправляю сообщение, срабатывает событие, которое вызывает функцию sendMessage() во viewModel, там я обновляю state, я выяснил, что можно даже так его обновлять, getMessages() в корутине снова запускается и обновляет state. НО, проблема в том, что обновляется state только у отправителя сообщения, а у других пользователей нет, им нужно либо в клавиатуре что-то вести, либо перезапустить чат, чтобы state обновился.
Уже обращался много где со своей проблемой, но никто так и не смог внятно мне объяснить ничего. Мне сообщили, что можно каким-то образом подписаться на push, который я вызываю в своём repository:
override fun sendMessage(message: MessageModel) {
messagesRef.push().setValue(message)
}
Но на что тут подписываться? Не ясно. Этот момент решили оставить без особых подробностей. Может кто-то сможет объяснить? Буду очень благодарен.
sendMessage() в ViewModel:
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("SimpleDateFormat")
private fun sendMessage(text: String) {
val calendar: Calendar = Calendar.getInstance()
val currentDate = LocalDate.now()
val time = SimpleDateFormat("HH:mm")
val currentMonthName = currentDate.month.getDisplayName(
TextStyle.FULL, Locale.getDefault()
)
val message = MessageModel(
name = Firebase.auth.currentUser?.displayName.toString(),
text = text,
time = time.format(calendar.time),
isMine = false,
sender = Firebase.auth.currentUser?.uid.toString(),
date = currentDate.dayOfMonth.toString() + " " + currentMonthName,
isNewDate = false
)
viewModelScope.launch {
repository.addMessage(message)
_uiState.value.counter += 1
}
}
getMessages() в ViewModel:
private fun getMessages() {
_uiState.update { currentState ->
currentState.copy(
isLoading = true
)
}
viewModelScope.launch {
var i = 0
repository.getMessages()
.map { messages ->
_messagesItemsSenders.add(messages.get(0).sender)
_messagesDates.add(messages.get(0).date)
_messagesPaddingMineAfterLastOther.add(messages.get(0).isMine)
// Check for new sender
if ((_messagesItemsSenders.size > 1) && (!messages.get(0).isMine) and
(_messagesItemsSenders[i] == _messagesItemsSenders[i-1])) {
messages.get(0).isMoreOne = true
}
// Check for new date
messages.get(0).isNewDate =
!((_messagesDates.size > 1) && (_messagesDates[i] == _messagesDates[i-1]))
// Set padding for first message that called "isMine"
messages.get(0).isPaddingMine = (_messagesPaddingMineAfterLastOther.size > 1) &&
(messages.get(0).isMine) and
(_messagesPaddingMineAfterLastOther[i]
!= _messagesPaddingMineAfterLastOther[i-1])
i += 1
ChatViewState(messages = messages, isLoading = false)
}
.collect() { newState ->
_uiState.value = newState
}
}