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?
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.
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With