Issue
When trying to invoke the Firebase Auth UI, using the below code the compiler throws java.lang.IllegalStateException: Launcher has not been initialized. Not sure, why the launcher is not initialized
@Composable
internal fun ProfileUI(profileViewModel: ProfileViewModel) {
val loginLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result != null) {
//do something
}
}
if (profileViewModel.isAnonymousUser) {
loginLauncher.launch(profileViewModel.buildLoginIntent())
} else {
}
}
override fun buildLoginIntent(): Intent {
val authUILayout = AuthMethodPickerLayout.Builder(R.layout.auth_ui)
.setGoogleButtonId(R.id.btn_gmail)
.setEmailButtonId(R.id.btn_email)
.build()
return AuthUI.getInstance().createSignInIntentBuilder()
.setIsSmartLockEnabled(!BuildConfig.DEBUG)
.setAvailableProviders(
listOf(
AuthUI.IdpConfig.EmailBuilder().build(),
AuthUI.IdpConfig.GoogleBuilder().build()
)
)
.enableAnonymousUsersAutoUpgrade()
.setLogo(R.mipmap.ic_launcher)
.setAuthMethodPickerLayout(authUILayout)
.build()
}
java.lang.IllegalStateException: Launcher has not been initialized
at androidx.activity.compose.ActivityResultLauncherHolder.launch(ActivityResultRegistry.kt:153)
at androidx.activity.compose.ManagedActivityResultLauncher.launch(ActivityResultRegistry.kt:142)
at androidx.activity.result.ActivityResultLauncher.launch(ActivityResultLauncher.java:47)
at com.madhu.locationbuddy.profile.ProfileUIKt.ProfileUI(ProfileUI.kt:37)
at com.madhu.locationbuddy.profile.ProfileUIKt.ProfileUI(ProfileUI.kt:15)
Any ideas on how to resolve this issue?
Solution
As per the Side-effects in Compose documentation:
Composables should be side-effect free.
Key Term: A side-effect is a change to the state of the app that happens outside the scope of a composable function.
Launching another activity, such as calling launch
, is absolutely a side effect and therefore should never be done as part of the composition itself.
Instead, you should put your call to launch within one of the Effect APIs, such as SideEffect
(if you want it to run on every composition) or LaunchedEffect
(which only runs when the input changes - that would be appropriate if profileViewModel.isAnonymousUser
was being driven by a mutableStateOf()
).
Therefore your code could be changed to:
internal fun ProfileUI(profileViewModel: ProfileViewModel) {
val loginLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result != null) {
//do something
}
}
if (profileViewModel.isAnonymousUser) {
SideEffect {
loginLauncher.launch(profileViewModel.buildLoginIntent())
}
} else {
// Output your UI, etc.
}
}
Answered By - ianhanniballake
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.