1
resposta

[Bug] Deslogar automático não desloga

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?

1 resposta

Olá Kurt!

Pelo que entendi, você está enfrentando um problema em relação ao comportamento inesperado do código ao implementar o "Deslogar Automático" no seu projeto final do curso. Acredito que a sua teoria sobre a edição do DataStore em threads separadas pode ser a causa desse problema.

Uma possível solução para evitar esse comportamento inesperado é tentar utilizar a função suspend com o "await" para realizar a edição do DataStore de forma sequencial. Dessa forma, você garante que o LaunchedEffect perceba a mudança antes de prosseguir para a navegação para a tela de Login.

Você pode modificar o trecho de código onde você realiza a edição do DataStore da seguinte maneira:

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) }.await() // Utilize o await() para esperar a conclusão da edição do DataStore
    }
}

Dessa forma, o LaunchedEffect só será executado após a conclusão da edição do DataStore, garantindo que a mudança seja percebida a tempo.

Espero ter ajudado e bons estudos!