question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

SavedStateViewModelFactory constructed with empty constructor supports only calls to create(modelClass: Class<T>, extras: CreationExtras)

See original GitHub issue

I am getting SavedStateViewModelFactory constructed with empty constructor supports only calls to create(modelClass: Class, extras: CreationExtras) errors when createBiometricPrompt() is called in the code below:

@HiltAndroidApp
class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // Logging
        Timber.plant(Timber.DebugTree())
    }
}
@OptIn(
    ExperimentalAnimationApi::class,
    ExperimentalMaterialApi::class,
    ExperimentalComposeUiApi::class,
    ExperimentalFoundationApi::class
)
@AndroidEntryPoint
class MainActivity : FragmentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        WindowCompat.setDecorFitsSystemWindows(window, false)
        setContent {
            MyTheme() {
                ProvideWindowInsets {
                    Navigation()
                }
            }
        }
    }
@OptIn(
    ExperimentalAnimationApi::class,
    ExperimentalMaterialApi::class,
    ExperimentalComposeUiApi::class,
    ExperimentalFoundationApi::class
)
@Composable
fun Navigation(
   // other params...
    authViewModel: AuthViewModel = hiltViewModel(),
   // other params...
) {

    Root( ) { scaffoldState, coroutineScope ->
        AnimatedNavHost(
            navController = navController,
            startDestination = //...
        ) {
          
            composable(route = Screen.Auth.name) {
                // fixme: this crashes with `SavedStateViewModelFactory constructed with empty constructor supports only calls to create(modelClass: Class, extras: CreationExtras)`
                BiometricPromptDialog(
                    biometricPrompt = authViewModel.createBiometricPrompt(
                        activity = LocalContext.current as FragmentActivity,
                        onSuccess = {
                            navController.navigate(/* some screen */) {
                                // remove biometric screen from back stack
                                popUpTo(/* some screen *) {
                                    inclusive = true
                                }
                            }
                        }
                    ),
                      // other params...
            }
            // other composable()
        }
    }
}
@HiltViewModel
class AuthViewModel @Inject constructor(
    @BiometricSupported isBiometricAuthSupported: Boolean,
    @IoDispatcher private val ioDispatcher: CoroutineDispatcher,
    private val preferenceDataStore: PreferenceDataStore
) : ViewModel() {

// other code...

fun createBiometricPrompt(
        activity: FragmentActivity,
        onSuccess: (BiometricPrompt.AuthenticationResult) -> Unit
    ): BiometricPrompt {
        val executor = ContextCompat.getMainExecutor(activity)

        val callback = object : BiometricPrompt.AuthenticationCallback() {
            override fun onAuthenticationError(errCode: Int, errString: CharSequence) {
                super.onAuthenticationError(errCode, errString)
                Timber.e("Error authenticating. Code $errCode ($errString")
                promptState = BiometricPromptState.ERROR
            }

            override fun onAuthenticationFailed() {
                super.onAuthenticationFailed()
                Timber.e("Biometric authentication failed.")
                promptState = BiometricPromptState.FAIL
            }

            override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
                super.onAuthenticationSucceeded(result)
                Timber.d("Authentication successful")
                promptState = BiometricPromptState.SUCCESS
                onSuccess(result)
            }
        }
        return BiometricPrompt(activity, executor, callback)
    }
}
buildscript {
    
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:7.1.1")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
        classpath("com.google.dagger:hilt-android-gradle-plugin:2.40.5"
    }
}

tasks.register("clean", Delete::class) {
    delete(rootProject.buildDir)
}
plugins {
    id("com.android.application")
    kotlin("android")
    id("kotlin-parcelize")
    kotlin("kapt")
    id("dagger.hilt.android.plugin")
    id("com.google.protobuf") version "0.8.12"
    id("com.mikepenz.aboutlibraries.plugin") version "10.0.0-b08"
}

dependencies {
    // other dependencies...


    implementation("com.google.dagger:hilt-android:2.40.5")
    kapt("com.google.dagger:hilt-compiler:2.40.5}")
    kapt("androidx.hilt:hilt-compiler:1.0.0")
    implementation("androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03")
    implementation("androidx.hilt:hilt-navigation-compose:1.0.0")

    // other dependencies...
}

The error occurs also when creating an instance of AuthViewModel in MainActivity and passing it down as a parameter to Navigation() (instead of using hiltViewModel())

private val authViewModel by viewModels<AuthViewModel>()

Can’t seem to figure this one out. What step can I take to find the source of the issue? Any pointer is appreciated, thanks!

Full crash log:

2022-02-06 22:35:29.957 31668-31668/com.my.package E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.my.package, PID: 31668
    java.lang.UnsupportedOperationException: SavedStateViewModelFactory constructed with empty constructor supports only calls to create(modelClass: Class<T>, extras: CreationExtras).
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:165)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:220)
        at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:111)
        at androidx.lifecycle.ViewModelProvider$Factory.create(ViewModelProvider.kt:79)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:168)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:137)
        at androidx.biometric.BiometricPrompt.getViewModel(BiometricPrompt.java:1029)
        at androidx.biometric.BiometricPrompt.<init>(BiometricPrompt.java:847)
        at com.my.package.viewmodel.AuthViewModel.createBiometricPrompt(AuthViewModel.kt:105)
        at com.my.package.navigation.NavigationKt$Navigation$13$1$1.invoke(Navigation.kt:165)
        at com.my.package.navigation.NavigationKt$Navigation$13$1$1.invoke(Navigation.kt:162)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9$1.invoke(AnimatedNavHost.kt:212)
        at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9$1.invoke(AnimatedNavHost.kt:210)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
        at androidx.compose.runtime.saveable.SaveableStateHolderImpl.SaveableStateProvider(SaveableStateHolder.kt:84)
        at androidx.navigation.compose.NavBackStackEntryProviderKt.SaveableStateProvider(NavBackStackEntryProvider.kt:60)
        at androidx.navigation.compose.NavBackStackEntryProviderKt.access$SaveableStateProvider(NavBackStackEntryProvider.kt:1)
        at androidx.navigation.compose.NavBackStackEntryProviderKt$LocalOwnersProvider$1.invoke(NavBackStackEntryProvider.kt:52)
        at androidx.navigation.compose.NavBackStackEntryProviderKt$LocalOwnersProvider$1.invoke(NavBackStackEntryProvider.kt:51)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
        at androidx.navigation.compose.NavBackStackEntryProviderKt.LocalOwnersProvider(NavBackStackEntryProvider.kt:47)
        at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9.invoke(AnimatedNavHost.kt:210)
        at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9.invoke(AnimatedNavHost.kt:202)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.animation.AnimatedContentKt$AnimatedContent$5$1$4.invoke(AnimatedContent.kt:658)
        at androidx.compose.animation.AnimatedContentKt$AnimatedContent$5$1$4.invoke(AnimatedContent.kt:648)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.animation.AnimatedVisibilityKt.AnimatedEnterExitImpl(AnimatedVisibility.kt:935)
        at androidx.compose.animation.AnimatedVisibilityKt.AnimatedVisibility(AnimatedVisibility.kt:606)
2022-02-06 22:35:29.958 31668-31668/com.my.package E/AndroidRuntime:     at androidx.compose.animation.AnimatedContentKt$AnimatedContent$5$1.invoke(AnimatedContent.kt:638)
        at androidx.compose.animation.AnimatedContentKt$AnimatedContent$5$1.invoke(AnimatedContent.kt:625)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.animation.AnimatedContentKt.AnimatedContent(AnimatedContent.kt:671)
        at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:197)
        at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:91)
        at com.my.package.navigation.NavigationKt$Navigation$13.invoke(Navigation.kt:151)
        at com.my.package.navigation.NavigationKt$Navigation$13.invoke(Navigation.kt:150)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at com.my.package.ui.components.RootKt$Root$3$4.invoke(Root.kt:215)
        at com.my.package.ui.components.RootKt$Root$3$4.invoke(Root.kt:214)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
        at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
        at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
        at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:142)
        at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2158)
        at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2413)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2594)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2580)
        at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:247)
        at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
        at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2580)
        at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:2556)
        at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:624)
        at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:795)
        at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:106)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:465)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:434)
        at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
        at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:947)
        at android.view.Choreographer.doCallbacks(Choreographer.java:761)
        at android.view.Choreographer.doFrame(Choreographer.java:693)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:17 (6 by maintainers)

github_iconTop GitHub Comments

6reactions
danysantiagocommented, Mar 10, 2022

Hey - Wanted to share an update that a change in androidx is going to fix this issue and if all goes well, it will be available in a future alpha version of androidx’s activity, fragment and viewmodel-savedstate artifacts.

2reactions
TylerMcCrawcommented, Mar 29, 2022

Just wanted to update anyone listening out here. The latest alpha versions (updated March 23) of the relevant androidx libraries fix this particular issue for me 🎉

Read more comments on GitHub >

github_iconTop Results From Across the Web

SavedStateViewModelFactory constructed with empty ...
UnsupportedOperationException : SavedStateViewModelFactory constructed with empty constructor supports only calls to create(modelClass: Class, ...
Read more >
SavedStateViewModelFactory - Android Developers
ViewModelProvider.Factory that can create ViewModels accessing and contributing to a saved state via SavedStateHandle received in a constructor.
Read more >
SavedStateViewModelFactory constructed with empty ...
We have an issue with HiltViewModelFactory. It calls create method without passing new CreationExtras values. I assume this should be fixed in hilt...
Read more >
AbstractSavedStateViewModelF...
"AbstractSavedStateViewModelFactory constructed ". + "with empty constructor supports only calls to ". + "create(modelClass: Class<T>, extras: ...
Read more >
Class androidx.lifecycle.AbstractSavedStateViewModelFactory
... constructed " + "with empty constructor supports only calls to " + "create(modelClass: Class<T>, extras: CreationExtras).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found