tom*_*fic 9 android kotlin firebase firebase-authentication kotlin-coroutines
我正在构建一个客户端应用程序,它使用 Firebase 来做两件事:
我已成功在客户端和后端服务器上正确设置所有内容(使用 Firebase 的 Admin SDK),并且能够正确验证用户身份并允许他们读取/写入数据库。
我还使用 Retrofit2 将请求从客户端发送到后端。
作为允许用户访问数据库的一部分,需要将用户的令牌发送到后端,以便验证用户。
为此,我有以下逻辑:
val user = FirebaseAuth.getInstance().currentUser
if (user != null) {
user.getIdToken(false).addOnCompleteListener {
if (it.isSuccessful) {
val token = it.result?.token
//retrofit logic to send request happens from here
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,获取用户的 Id 令牌是一个异步调用,在我当前的代码库中,我对后端的每次调用都有这个代码块(重复)。
我想知道如何将此代码片段导出到函数(也许是挂起方法?),以便可以在每次调用后端时重用它
我在网上搜索过,看到了很多SO问题,但没有一个适合这种情况。我考虑过传递回调,但是我有几种与后端通信的方法,并且每个方法都需要不同的回调方法。
我正在寻找的解决方案看起来像这样:
fun fetchDataFromDB() {
getIdTokenForUser()
//wait till it finishes and then
//perform request to DB
}
fun updateDataInDB() {
getIdTokenForUser()
//wait till it finishes and then
//perform request to DB
}
//......
Run Code Online (Sandbox Code Playgroud)
我尝试过阅读和实现协程,但我缺乏正确执行此操作的知识。
编辑
感谢@Doug Stevenson 的回答和指导,我已经成功构建了以下内容:
private suspend fun getUserIdToken(user: FirebaseUser) = coroutineScope {
val job = async {
user.getIdToken(false).result?.token
}
job.await()
}
Run Code Online (Sandbox Code Playgroud)
我以这种方式使用它:
fun updateDB(context: Context) = runBlocking {
val user = FirebaseAuth.getInstance().currentUser
if (user != null) {
val token = getUserIdToken(user)
}
}
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?由于下面给出的答案提出了不同的实现。
Dou*_*son 20
getIdToken异步返回一个Task对象。如果要在 Kotlin 协程中使用 Task 对象,可以使用库kotlinx-coroutines-play-services向 Task添加扩展方法await(),使其可以在协程中使用。这样,您就可以编写如下内容:
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.3.9"
Run Code Online (Sandbox Code Playgroud)
import kotlinx.coroutines.tasks.await
suspend fun getIdTokenForUser(user: FirebaseUser): GetTokenResult {
return try {
user.getIdToken(false).await()
}
catch (e: Exception) {
// handle error
}
}
Run Code Online (Sandbox Code Playgroud)
您可能必须在这里更新类型 - 我没有尝试编译或测试它。
也可以看看:
| 归档时间: |
|
| 查看次数: |
10521 次 |
| 最近记录: |