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.

coroutineDispatcher
  • 7,718
  • 6
  • 30
  • 58

0 Answers0