Why is my token-based auth not navigating to the home screen after a successful...
source link: https://stackoverflow.com/questions/73557074/why-is-my-token-based-auth-not-navigating-to-the-home-screen-after-a-successful
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Why is my token-based auth not navigating to the home screen after a successful login?
I just built a token based login function in material3 jetpack compose that will save the token if the login is successful. I tried following an article on how to save the auth token from API. I am using Laravel sanctum as my auth API.
I am confused with this problem because the function is working as it displays the login failed dialog if the credentials is incorrect as it supposed to be, however, it doesn't navigate to the home screen if the credentials is correct. I don't know what is the exact problem here because there are no errors thrown in the logcat during runtime.
This is my LoginViewModel.kt, it handles the logic of my login function
class LoginViewModel(application : Application) : AndroidViewModel(application)
{
val isSuccessLoading = mutableStateOf(false)
val loginFailedDialog = mutableStateOf(false)
val progressBar = mutableStateOf(false)
val loginRequestLiveData = MutableLiveData<Boolean>()
private lateinit var sessionManager: SessionManager
private lateinit var apiClient: ApiClient
@SuppressLint("StaticFieldLeak")
private val context = getApplication<Application>().applicationContext
fun login(email: String,
password: String,
device_name : String = "android")
{
sessionManager = SessionManager(context)
apiClient = ApiClient()
viewModelScope.launch(Dispatchers.IO) {
val loginInfo = LoginRequest(email, password, device_name)
progressBar.value = true
apiClient.getApiService(context).login(loginInfo)
.enqueue(object : Callback<LoginResponse> {
override fun onResponse(
call : Call<LoginResponse> ,
response : Response<LoginResponse>
)
{
val loginResponse = response.body()
if (loginResponse?.statusCode == 200 && loginResponse.user != null)
{
sessionManager.saveAuthToken(loginResponse.authToken)
viewModelScope.launch {
delay(500L)
isSuccessLoading.value = true
}
}
else
{
response.errorBody()?.let { error ->
viewModelScope.launch {
loginFailedDialog.value = true
delay(3500L)
loginFailedDialog.value = false
error.close()
}
}
}
loginRequestLiveData.postValue(response.isSuccessful)
progressBar.value = false
}
override fun onFailure(call : Call<LoginResponse> , t : Throwable)
{
Log.d("Logging" , "Error Authentication" , t)
progressBar.value = false
}
})
}
}
}
Then here is my MainActivity.kt:
@AndroidEntryPoint
class MainActivity : ComponentActivity()
{
override fun onCreate(savedInstanceState : Bundle?)
{
super.onCreate(savedInstanceState)
val loginViewModel = LoginViewModel(application)
setContent {
MobileApp(loginViewModel)
}
ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content)) { view , insets ->
val bottom = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
view.updatePadding(bottom = bottom)
insets
}
}
}
@Composable
fun MobileApp(loginViewModel : LoginViewModel){
val navController = rememberNavController()
val scrollState = rememberScrollState()
NavHost(navController = navController ,
startDestination = AuthScreens.Splash.route)
{
//Splash screen
composable(route = AuthScreens.Splash.route){
SplashScreen(navController = navController)
}
//Login screen
composable(route = AuthScreens.Login.route){
val forgotDialog = remember { mutableStateOf(false)}
val loginError = loginViewModel.loginFailedDialog.value
val loadingProgressBar = loginViewModel.progressBar.value
if (loginViewModel.isSuccessLoading.value) {
LaunchedEffect(key1 = Unit) {
navController.navigate(route = AuthScreens.AppScaffold.route) {
popUpTo(route = AuthScreens.Login.route) {
inclusive = true
}
}
}
} else {
LoginScreen(
navController = navController ,
scrollState = scrollState ,
onclickLogin = loginViewModel::login ,
forgotDialog = forgotDialog ,
loginError = loginError ,
loadingProgressBar = loadingProgressBar)
}
}
//Registration screen
composable(route = AuthScreens.Register.route) {
RegistrationScreen(navController = navController , scrollState = scrollState)
}
//App scaffold
composable(route = AuthScreens.AppScaffold.route){
AppScaffold(navController = navController)
}
}
}
Then here is the AppScaffold:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppScaffold(navController : NavController)
{
Scaffold(//scaffold params)
{
NavigationHost(navController = navController)
}
}
Then the navigation host:
@Composable
fun NavigationHost(navController : NavController)
{
NavHost(navController = navController as NavHostController ,
startDestination = MainScreens.Home.route)
{
composable(route = MainScreens.Home.route) {
HomeScreen(navController = navController)
}
}
}
I don't know if it is because of my LoginResponse. My LoginResponse data class looks like this
data class LoginResponse(
@SerializedName("status_code") var statusCode : Int ,
@SerializedName("auth_token") var authToken : String ,
@SerializedName("user") var user : User?)
and here is the return if the login is successful using postman
{
"token": "137|HCFJvwPeNKgZihNSwztPqnfwSntwSzVhkaaYZGX7"
}
Can someone help me with this problem?
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK