SomeKoder
SomeKoder

Reputation: 915

Dagger hilt & oauth interceptor - How to update Singleton

I am using Hilt for dependency injection. I'm trying to implement a oauth interceptor that will authenticate my request after login.

The problem I am having is related to the oauthManager(context).getToken(), etc. OauthManager is essentially just a class for accessing EncryptedSharedPreferences. But since my provides method is a Singleton, any updates I make to the shared prefs will not reflect to my okhttp instance.

The app starts out not authenticated, and becomes at a later point. I can probably solve this using another scope like ViewModelScoped, but I want to know if there's a better way of updating the oauth credentials.

@Singleton
@Provides
@Named(NAME_WITH_OAUTH)
fun provideOkHttp(
    @ApplicationContext context: Context
) = OkHttpClient
        .Builder()
        .addInterceptor(
            OauthInterceptor(
                consumerKey = Constants.CONSUMER_KEY,
                consumerSecret = Constants.CONSUMER_SECRET,
                accessToken = oauthManager(context).getToken(),
                accessSecret = oauthManager(context).getSecret(),
                verifier = oauthManager(context).getVerifier()
            )
        )
        .build()

Thanks in advance!

Upvotes: 1

Views: 1125

Answers (1)

Nikola Despotoski
Nikola Despotoski

Reputation: 50578

This is hardly hilt problem, but structural problem.

You are passing the arguments to the Interceptor way ahead, instead when needed.

You need to inject the Interceptor instead of creating the instance as you down.

@Provides fun provideMyInterceptor(authManager : AuthManager){
    return OAuthInterceptor(
                consumerKey = Constants.CONSUMER_KEY,
                consumerSecret = Constants.CONSUMER_SECRET,
                authManager = authManager)

}

@Singleton
@Provides
@Named(NAME_WITH_OAUTH)
fun provideOkHttp(oAuthInterceptor : OAuthInterceptor) = OkHttpClient
        .Builder().addInterceptor(oAuthInterceptor).build()

Interceptor class should depend on your AuthManager.

class OAuthInterceptor(
     private val consumerKey : String,
     private val consumerSecret : String,
     private val authManager : AuthManager)

private val accessToken get() = authManager.getAccessToken()

/** other code reducted **/

Please note that getter will call getAccessToken() each time the property is accessed.

Alternatively, you can use Provider<String> for your token. Calling tokenProvider.get() will request the Provider to supply new snapshot of that instance each call.

Upvotes: 1

Related Questions