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

如何修复Google OneTapClient错误16(找不到匹配凭据)?

Google One Tap认证突然失效,点击登录直接抛异常的排查与修复

问题描述

使用Jetpack Compose开发Android应用,此前Google用户认证功能正常,已完成Firebase项目关联、启用Google认证、配置SHA-1密钥、指定Web Client ID并添加google-services.json文件。但近期点击登录按钮时,不再显示Google账号列表或登录表单,直接抛出异常,异常在signIn()方法的await函数中捕获,Task的isSuccessful为false。

相关代码

GoogleAuthClient类

class GoogleAuthClient(
    private val context: Context,
    private val oneTapClient: SignInClient
) {
    private val auth = Firebase.auth

    suspend fun <T> Task<T>.await(): T {
        return suspendCancellableCoroutine { continuation ->
            addOnCompleteListener {
                if (it.isSuccessful) {
                    continuation.resume(it.result, null)
                } else {
                    continuation.cancel(it.exception ?: Exception("Something went wrong during await"))
                }
            }
        }
    }

    suspend fun signIn(): IntentSender? {
        val result = try {
            oneTapClient.beginSignIn(
                buildSignInRequest()
            ).await()
        } catch (e: Exception) {
            e.printStackTrace()
            if (e is CancellationException) throw e
            null
        }
        return result?.pendingIntent?.intentSender
    }

    suspend fun signInWithIntent(intent: Intent): SignInResult {
        val credential = oneTapClient.getSignInCredentialFromIntent(intent)
        val googleIdToken = credential.googleIdToken
        val googleCredentials = GoogleAuthProvider.getCredential(googleIdToken, null)
        return try {
            val user = auth.signInWithCredential(googleCredentials).await().user
            SignInResult(data = user?.run {
                UserData(
                    userId = uid,
                    username = displayName,
                    profilePicUrl = photoUrl?.toString()
                )
            }, errorMessage = null)
        } catch (e: Exception) {
            e.printStackTrace()
            if (e is CancellationException) throw e
            SignInResult(data = null, errorMessage = e.message)
        }
    }

    private fun buildSignInRequest(): BeginSignInRequest {
        return BeginSignInRequest.builder()
            .setGoogleIdTokenRequestOptions(
                GoogleIdTokenRequestOptions.builder()
                    .setSupported(true)
                    .setFilterByAuthorizedAccounts(false)
                    .setServerClientId(context.getString(R.string.def_web_client_id))
                    .build()
            )
            .setAutoSelectEnabled(true)
            .build()
    }

}

调用代码

val viewModel = viewModel<SignInViewModel>()
val state by viewModel.state.collectAsState()

val launcher = rememberLauncherForActivityResult(
    contract = ActivityResultContracts.StartIntentSenderForResult(),
    onResult = {result ->
        if (result.resultCode == RESULT_OK) {
            lifecycleOwner.lifecycleScope.launch {
                val signInResult = authClient.signInWithIntent(
                    intent = result.data ?: return@launch
                )
                // Here we already got the result from the intent
                viewModel.onSigninResult(signInResult)
                if (signInResult.data != null)
                    navController.navigate(NavigationScreen.GoalSelection.name)
                else
                    Toast.makeText(context, "Something went wrong during singin.", Toast.LENGTH_LONG)
            }
        }

    }
)
GoogleSignInButton(
    state = state,
    onGoogleSignIn = {
        lifecycleOwner.lifecycleScope.launch {
            val signinIntentSender = authClient.signIn()
            launcher.launch(
                IntentSenderRequest.Builder(
                    signinIntentSender ?: return@launch
                ).build()
            )
        }
    }
)


@Composable
fun GoogleSignInButton(
    state: SignInState,
    onSigninClick: () -> Unit
) {
    val context = LocalContext.current
    LaunchedEffect(key1 = state.signInError) {
        state.signInError?.let { error ->
            Toast.makeText(
                context,
                error,
                Toast.LENGTH_LONG
            ).show()
        }
    }
    Button(onClick = onSigninClick) {
        Text(text = "Continue with Google")
    }
}

可能的原因及修复方案

1. Google Play服务版本不兼容

  • 原因:设备上的Google Play服务版本过低,或与依赖的Google Auth库版本不匹配,导致One Tap认证流程无法正常初始化。
  • 修复:
    • 前往Google Play商店更新设备上的Google Play服务至最新版本。
    • 使用Firebase BOM统一管理依赖版本,避免版本冲突:
      dependencies {
          implementation platform('com.google.firebase:firebase-bom:32.7.0')
          implementation 'com.google.firebase:firebase-auth'
          implementation 'com.google.android.gms:play-services-auth'
      }
      

2. Web Client ID配置异常

  • 原因:R.string.def_web_client_id对应的ID有误,或Firebase控制台中该ID的配置发生变更。
  • 修复:
    • 打开Firebase控制台,进入项目「Authentication」->「登录方法」->「Google」,确认Web应用的Client ID与google-services.json中client_oauth_client下的client_id一致。
    • 重新下载最新的google-services.json替换项目中的旧文件,同步Gradle。

3. 设备认证缓存或服务临时故障

  • 原因:设备上的Google账号认证缓存异常,或One Tap服务临时故障。
  • 修复:
    • 清除应用的缓存和数据,或在设备「设置」->「Google」->「管理你的Google账号」->「安全」->「第三方应用的访问权限」中移除当前应用权限后重新授权。
    • 暂时关闭自动选择账号功能,修改buildSignInRequest():
      private fun buildSignInRequest(): BeginSignInRequest {
          return BeginSignInRequest.builder()
              .setGoogleIdTokenRequestOptions(
                  GoogleIdTokenRequestOptions.builder()
                      .setSupported(true)
                      .setFilterByAuthorizedAccounts(false)
                      .setServerClientId(context.getString(R.string.def_web_client_id))
                      .build()
              )
              .setAutoSelectEnabled(false)
              .build()
      }
      

4. 异步调用异常处理不完整

  • 原因:当前await()扩展函数仅处理onCompleteListener,遗漏了Task的其他失败场景,导致异常信息被掩盖。
  • 修复:优化await()函数并打印完整异常堆栈:
    suspend fun <T> Task<T>.await(): T {
        return suspendCancellableCoroutine { continuation ->
            addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    continuation.resume(task.result, null)
                } else {
                    continuation.cancel(task.exception ?: Exception("Task failed"))
                }
            }
            addOnFailureListener { exception ->
                continuation.cancel(exception)
            }
            continuation.invokeOnCancellation {
                if (!isComplete) cancel()
            }
        }
    }
    
    同时在signIn()中打印详细异常:
    suspend fun signIn(): IntentSender? {
        val result = try {
            oneTapClient.beginSignIn(buildSignInRequest()).await()
        } catch (e: Exception) {
            Log.e("GoogleAuthClient", "Sign in failed", e)
            if (e is CancellationException) throw e
            null
        }
        return result?.pendingIntent?.intentSender
    }
    

5. 应用签名配置变更

  • 原因:近期修改了应用签名配置(如切换调试/正式签名、重新生成密钥),导致Firebase控制台的SHA-1指纹与当前应用签名不匹配。
  • 修复:
    • 使用keytool生成当前签名文件的SHA-1指纹:
      keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
      
    • 前往Firebase控制台「设置」->「应用」->「添加指纹」,添加新的SHA-1指纹,重新下载google-services.json并同步项目。

内容的提问来源于stack exchange,提问作者Zay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 14:50:06