You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次启动应用时Credential Manager调用Google登录/注册流程两次均失败,抛出NoCredentialsException

首次启动应用时Credential Manager调用Google登录/注册流程两次均失败,抛出NoCredentialsException

我最近碰到个头疼的Google登录问题,想跟大家聊聊:

用户首次从Play Store下载我的应用后,尝试通过Google登录时,不管是走「已有应用账号」的登录流程,还是「新用户注册」流程,都会直接抛出NoCredentialsException失败。但神奇的是,有时候只要做一些无关操作,比如重启应用(杀死进程再打开,不过也不是次次生效)、旋转设备,甚至只是在引导页随便点个按钮、切到桌面再切回应用,登录功能就突然正常了——而且这些操作也不是每次都能触发成功,完全没规律。

我已经试过好几种方案了,但都没解决问题:

  • 最开始我是用Activity上下文初始化的CredentialManager,后来换成通过Koin注入Application上下文,想着可能是UI上下文的生命周期问题,但没用;
  • 把GetGoogleIdOption换成GetSignInWithGoogleOption,依然没效果;
  • 偶然发现有时候在引导页点击某个元素后再发起登录请求,居然能成功,但这完全不是可依赖的解决方案。

我还注意到Google的Issue Tracker上有类似的未修复问题,但显然官方还没跟进。

下面是我当前的GoogleAuthClient实现代码:

actual class GoogleAuthClient(
    private val activityProvider: ActivityProvider,
    private val manager: CredentialManager
) {
    actual suspend fun getIdToken(clientId: String): String? {
        val activity = activityProvider.currentActivity() ?: return null

        val signIn = GetGoogleIdOption.Builder()
            .setServerClientId(clientId)
            .setFilterByAuthorizedAccounts(true)
            .setAutoSelectEnabled(true)
            .build()

        val signUp = GetGoogleIdOption.Builder()
            .setServerClientId(clientId)
            .setFilterByAuthorizedAccounts(false)
            .setAutoSelectEnabled(false)
            .build()

        val trySignIn = GetCredentialRequest.Builder().addCredentialOption(signIn).build()
        val trySignUp = GetCredentialRequest.Builder().addCredentialOption(signUp).build()

        val response = try {
            manager.getCredential(activity, trySignIn)
        } catch (e: NoCredentialException) {
            CrashReporter.recordException(e)
            try {
                manager.getCredential(activity, trySignUp)
            } catch (e: NoCredentialException) {
                CrashReporter.log("No credentials found for the second time")
                CrashReporter.recordException(e)
                return null
            }
        } catch (e: CancellationException) {
            throw e
        } catch (e: Exception) {
            CrashReporter.recordException(e)
            return null
        }

        return handleSignIn(response.credential)
    }

    private fun handleSignIn(credential: Credential): String? {
        if (credential is CustomCredential && credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
            return try {
                GoogleIdTokenCredential.createFrom(credential.data).idToken
            } catch (e: GoogleIdTokenParsingException) {
                CrashReporter.recordException(e); null
            }
        }
        return null
    }

    actual suspend fun signOut() {
        try {
            manager.clearCredentialState(ClearCredentialStateRequest())
        } catch (e: CancellationException) {
            throw e
        } catch (e: Exception) {
            CrashReporter.recordException(e)
        }
    }
}

有没有朋友遇到过类似的情况?或者有什么我没考虑到的排查方向吗?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 07:34:31