'how can i use jectpack datastore in okhttp Interceptor? it need a context object
i wanna add a token to request headers in Interceptor . but now i dont now what should i do.
here is my datastore
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
class SettingsManager(context: Context) {
private val dataStore = context.dataStore
val getToken = dataStore.data
.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map { preference ->
preference[token] ?: ""
}
suspend fun setToken(tokenStr: String) {
dataStore.edit { preferences ->
preferences[token] = tokenStr
}
}
companion object {
val token = stringPreferencesKey("token")
}
}
i can not get the context object in Interceptor 。
so i try to use hilt to fix it
class RequestInterceptor(private val settingsManager: SettingsManager) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
runBlocking {
val first = settingsManager.getToken.first()
LogUtil.i("token " + first)
request.newBuilder().addHeader("token", first).build();
}
return chain.proceed(request)
}
}
i dont know the next step @AndroidEntryPoint cant use on Interceptor class .
plz guys , give me some solutions
Solution 1:[1]
You should be able to see it in Hilt if you just add the @Inject constructor to your RequestInterceptor.
E.g.
class RequestInterceptor @Inject constructor(private val settingsManager: SettingsManager) : Interceptor {...
And I'm not sure if you can do your SettingsManager like that but you can try class SettingsManager @Inject constructor(@ApplicationContext context: Context) {
Solution 2:[2]
I just used this way.
suspend fun getToken() : String? {
val preference = dataStore.data.first()
return preference[PREF_JWT_TOKEN]
} // this is inside the datastore local repository.
and inside the intercepter you can get runBlocking UI as this.
val builder = Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
val client = OkHttpClient.Builder()
.addInterceptor { chain ->
val original = chain.request()
var token: String? = null
runBlocking {
token = dataStorePreferenceRepository.getToken()
if (!token.isNullOrEmpty()) {
val authorized = original.newBuilder()
.addHeader("Authorization", "Bearer $token")
.build()
chain.proceed(authorized)
} else {
chain.proceed(original)
}
}
}.addNetworkInterceptor(StethoInterceptor()).build()
return builder.client(client).build().create(ApiInterface::class.java)
and inside the Module class use like this.
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun getDataStorePreferenceRepository(@ApplicationContext appContext: Context): DataStorePreferenceRepository {
return DataStorePreferenceRepository(context = appContext)
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Barry Irvine |
| Solution 2 | Prabudda Fernando |
