同步获取 Firebase 用户令牌

OCD*_*Dev 7 android firebase firebase-authentication

我正在尝试获取 Firebase 令牌来验证我对 Rest API 的调用。我可以使用以下代码异步生成令牌。

    FirebaseUser mUser = App.getFirebaseAuth().getCurrentUser();
    if (mUser!=null) {
        mUser.getIdToken(false)
                .addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
                    public void onComplete(@NonNull Task<GetTokenResult> task) {
                        if (task.isSuccessful()) {
                            ID_TOKEN = task.getResult().getToken();
                        } else {
                            Log.e(App.TAG, "Firebase Token task ended with error.");
                        }
                    }
                });
    } else {
        Log.i(App.TAG,"User is null, no Firebase Token available");
    }
Run Code Online (Sandbox Code Playgroud)

ID_TOKEN 是保存结果的静态字符串变量。问题是,我正在构建我的请求并添加身份验证标头。

        headers.put("Authentication",
                "Bearer  + ID_TOKEN);
Run Code Online (Sandbox Code Playgroud)

问题是,由于 Firebase 令牌是异步检索的,有时 ID_TOKEN 变量为空。我尝试使用强制线程等待任务

任务.await(任务)

但是我收到一个异常,说不能在主线程中调用 await。

有没有其他方法可以同步获取令牌,或者让线程等待任务完成?

Boy*_*Boy 7

我现在这样做:

private suspend fun getTokenResult (firebaseUser: FirebaseUser) = suspendCoroutine<GetTokenResult?> { continuation ->
firebaseUser.getIdToken(true).addOnCompleteListener {
    if (it.isSuccessful) {
        continuation.resume(it.result)
    } else {
        continuation.resume(null)
    }
}
Run Code Online (Sandbox Code Playgroud)

使用挂起函数和延续机制。因此,如果您正在使用Coroutines,这可能是最简单的方法


Dou*_*son -1

强制某些东西在主线程上同步运行是一个非常糟糕的主意。它可能会锁定您的应用程序并可能导致 ANR。这就是为什么当你尝试运行时 Android 会抱怨Tasks.await()- 它知道可能存在问题。

最好学习如何进行异步编程,以正确的方式做到这一点。您必须在必须提供的侦听器中接收令牌。

请阅读此博客,详细了解 Firebase API 为何是异步的。

  • @DougStevenson 这只是假设你的 api 客户端的开发人员缺乏经验。任何 API 都应该首先提供同步访问,因为客户端可以有自己的异步访问方式。想想 rxjava,其中包装同步 api 比异步更简洁。您仍然可以通过博客为缺乏经验的开发人员推广自定义的异步访问(任务)方式,但恕我直言,不提供任何同步方式是一个糟糕的 API 设计。 (13认同)
  • 如果我们想在后台线程上同步获取令牌(我们可以手动编写)怎么办? (10认同)