0

Tried to solve this reading the docs, and also I followed this example. But I did not succeed. So I would need to find out what am I missing or doing wrong.

I have an app module, where the @HiltAndroidApp stands:

@HiltAndroidApp
class MyApp : Application() {

    override fun onCreate() {
        super.onCreate()
        ...
    }
}

Now I have a :core module where I have my FirebaseAuth dependency generated from a module:

@Module
@InstallIn(ApplicationComponent::class)
class FirebaseModule{
    @Provides
    fun provideFirebaseAuth() : FirebaseAuth = FirebaseAuth.getInstance()
}

And a :login module, in which I am stuck. Before continuing: :app module implements :core and :login modules.

Now I have created a LoginModuleDependencies in :core:

@EntryPoint
@InstallIn(ApplicationComponent::class)
interface LoginModuleDependencies {
    fun firebaseAuth(): FirebaseAuth
}

So I assume this one is used in order to expose the dependencies across dynamic features. Jumping to the LoginComponent (in the ':login' module), I do this:

@Component(dependencies = [LoginModuleDependencies::class])
interface LoginComponent {
    fun inject(loginFragment: LoginFragment)

    @Component.Factory
    interface Factory {
        fun create(
            loginModuleDependencies: LoginModuleDependencies
        ): LoginComponent
    }
}

Which according to the docs, allows me to do this:

@OptIn(ExperimentalCoroutinesApi::class)
class LoginFragment : Fragment(R.layout.fragment_login) {

    private val loginViewModel: LoginViewModel by viewModels()
    private var fragmentLoginBinding: FragmentLoginBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        DaggerLoginComponent.factory()
            .create(
                loginModuleDependencies = EntryPointAccessors.fromApplication(
                    requireActivity().applicationContext,
                    LoginModuleDependencies::class.java
                )
            ).inject(this)
        super.onCreate(savedInstanceState)
    }
...
}

The crash: RuntimeException: Cannot create an instance of class com.coroutinedispatcher.login.LoginViewModel Following the logs a little bit further:

Caused by: java.lang.InstantiationException: java.lang.Class<com.coroutinedispatcher.login.LoginViewModel> has no zero argument constructor

This is what assume that I am either missing something, or doing something wrong.

Because my LoginViewModel looks like this:

class LoginViewModel @ViewModelInject constructor(private val firebaseAuth: FirebaseAuth, @Assisted private val savedStateHandle: SavedStateHandle) : ViewModel()

I can verify that if I do field injection in the respective fragment, the FirebaseAuth instance is retrieved.

So, what I am currently doing wrong?

EDIT: So basically, I was able to confirm that I can pull from ApplicationComponent because doing this:

@Inject lateinit var firebaseAuth: FirebaseAuth

// onViewCreated
Log.d(someClassName, "value: ${::firebaseAuth.isInitialized}") // true

And also, creating a new normal class that pulls that dep, works:

class SomeWeirdClass @Inject constructor(private val firebaseAuth: FirebaseAuth)

Logging that on the Fragment

Log.d(someClassName, "value: ${::someWeirdClass.isInitialized}") // true

So I assume there might be a versioning problem, but I just cannot find out what. Providing a ViewModelProvider.Factory works, but what's the point in using it if you are supposed to use @ViewModelInject.

4
  • User AssistedInject constructor in your ViewModel and provide at least one Assisted argument in constructor. @coroutineDispatcher Commented Nov 8, 2020 at 14:26
  • 1
    I can't ignore your name :D @coroutineDispatcher Commented Nov 8, 2020 at 14:29
  • @AslamHossin Using Hilt you can use @ViewModelInject instead, you don't need to use @AssistedInject. But even if I do that, it's the same behaviour. I already tried it. Commented Nov 8, 2020 at 14:53
  • Where is @ ViewModelInject in your example? Commented Nov 8, 2020 at 23:01

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.