Как внедрить сервис модификации с токеном Firebase ID в кодеин - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь внедрить модифицированную услугу в kodien . Служба API использует маркер Firebase Auth для аутентификации. Поэтому я должен передать токен id в заголовке запроса как basi c auth путем получения токена из Firebase Auth.getInstance (). GetIdToken (), который выдает токен в обратном вызове Task. Теперь проблема, с которой я сталкиваюсь, заключается в том, что я должен передать токен перехватчику запросов HTTP-клиентов. Я не могу понять, как это сделать.

Я уже рассмотрел некоторые примеры Kotlin сопрограмм для решения. Но я новичок в Kotlin сопрограмм и не смог много пикапить.

Вот мой объект kodien.

override val kodein by Kodein.lazy {
    import(androidXModule(this@App))
    bind() from singleton { FirebaseDatabase.getInstance() }
    bind<ApiService>() from singleton {  RetrofitFactory.makeApiService() }
}

Моя модифицированная фабрика.

object RetrofitFactory {

    fun makeApiService(): ApiService {

        FirebaseAuth.getInstance().currentUser?.getIdToken(true)?.addOnCompleteListener {
            if (it.isSuccessful){
                // HERE IS THE TOKEN
                val token = it.result?.token
            }
        }

        val client = OkHttpClient.Builder()
                .addInterceptor {
                    val request = it.request().newBuilder()
                            .addHeader("authorization", "*** PASS TOKEN HERE ***")
                            .build()
                    it.proceed(request)
                }
                .build()

        return Retrofit.Builder()
                .client(client)
                .baseUrl(BuildConfig.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(ApiService::class.java)
    }

}

Я могу ошибаться или, может быть, есть лучший способ.

Любая помощь приветствуется.

Заранее спасибо.

1 Ответ

0 голосов
/ 07 марта 2020

Я нашел решение.

Создайте TokenProvider, как показано ниже

class TokenProvider {

    private var token: String = ""

    fun get() = token

    fun load() {
        getToken {
            token = it
        }
    }

    private fun getToken(callback: (String) -> Unit) {
        FirebaseAuth.getInstance().currentUser?.getIdToken(true)?.addOnCompleteListener {
            if (it.isSuccessful){
                callback(it.result?.token!!)
            }
        }
    }
} 

Введите TokenProvider в кодеин

override val kodein by Kodein.lazy {
    import(androidXModule(this@App))
    bind() from singleton { TokenProvider() }
    bind<ApiService>() with singleton { RetrofitFactory.makeApiService(instance()) }
}

Передайте TokenProvider в makeServiceApi в качестве параметра и используйте его.

object RetrofitFactory {

    fun makeApiService(tokenProvider: TokenProvider): ApiService {

        val token = tokenProvider.get()

        val client = OkHttpClient.Builder()
                .addInterceptor {
                    val request = it.request()
                            .newBuilder()
                            .addHeader("authorization", "Bearer $token")
                            .build()
                    it.proceed(request)
                }
                .build()

        return Retrofit.Builder()
                .baseUrl(BuildConfig.BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(ApiService::class.java)
    }
}

И, наконец, загрузите токен в приложении onCreate

override fun onCreate() {
    super.onCreate()
    val tokenProvider by instance<TokenProvider>()
    tokenProvider.load()
}

В этом решении есть крайний случай. Если вы позвоните в Api, как только приложение загрузится. К тому времени, если токен Firebase не загружен. Тогда вызов Api не удастся.

Это работает для меня, потому что я не вызываю Api on App load. Все еще ищу решение, которое может решить этот крайний случай. Одним из способов решения этой проблемы является ожидание загрузки токена перед вызовом Api.

...