No final do Treinamento, ao implementar o "Deslogar Automático" percebi que um comportamento inusitado do código, como podia ser um problema com alguma implementação minha, testei o Projeto Final do Curso sem alterar nem uma linha e o resultado foi o mesmo, tanto que os códigos a seguir são do Projeto Final:
Se rodar normal, ele deleta o usuário e apaga a preferencesKey com o método a seguir:
suspend fun apaga() {
usuarioDao.apaga(Usuario(idUsuario = _uiState.value.nomeUsuario))
if (nomeUsuario.equals(dataStore.data.first()[PreferencesKey.USUARIO_ATUAL])) {
dataStore.edit { it.remove(PreferencesKey.USUARIO_ATUAL) }
}
}
Debugando, notei que ele chega passar pelo SessãoViewModel para atualizar o state de "logado":
init {
viewModelScope.launch {
dataStore.data
.collect {
if (it[PreferencesKey.USUARIO_ATUAL] == null) {
desloga()
_uiState.value = _uiState.value.copy(
logado = false
)
}
}
}
}
O código detecta a preferencesKey nula e entra no bloco IF, atualiza a preferencesKey de logado de TRUE para FALSE e o State da Sessão, porém desse ponto em diante, o LaunchedEffect dentro do NavHost não entra em ação e não navega para o Login:
val viewModel= hiltViewModel<SessaoViewModel>()
val state = viewModel.uiState.collectAsState()
LaunchedEffect(key1 = state.value.logado){
if(!state.value.logado){
navController.navegaParaLoginElimpaBackStack()
}
}
Minha teoria é de que como a edição do DataStore atua em threads separadas, a edição ocorre em paralelo, não dando tempo pro LaunchedEffect perceber a mudança. O que reforça essa teoria é que se eu debugar e "alongar" o processo de edição do DataStore, o LaunchedEffect percebe a mudança a tempo e navega para a tela de Login.
Qual seriam outras maneiras de impedir esse comportamento inesperado?