Google One Tap登录addOnSuccessListener不触发,空引用错误求助
Google One Tap Sign In 回调不触发问题排查
问题现象
代码可正常运行,按钮可点击,但addOnSuccessListener始终不执行,仅能获取到监听器失败时的空引用错误。已按官方文档完成配置,排查过常见方案仍未解决,怀疑是Google Play Console或Firebase配置问题,但无法确定。
相关代码
MainActivity.kt
// Tags private val TAG_SIGNIN = "Google Sign In" private val TAG_FIREBASE = "Firebase backend auth" private val TAG_GOOGLE = "Google Sign In Results" @AndroidEntryPoint class MainActivity2 : ComponentActivity() { // Google Sign in private lateinit var oneTapClient: SignInClient private lateinit var signInRequest: BeginSignInRequest private lateinit var signUpRequest: BeginSignInRequest // Firebase private lateinit var auth: FirebaseAuth override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Firebase Auth Instantiate auth = Firebase.auth // Google Onetap Sign in oneTapClient = Identity.getSignInClient(this) signInRequest = BeginSignInRequest.builder() .setGoogleIdTokenRequestOptions( BeginSignInRequest.GoogleIdTokenRequestOptions.builder() .setSupported(true) .setServerClientId(getString(R.string.firebase_client_id)) .setFilterByAuthorizedAccounts(true) .build()) .setAutoSelectEnabled(true) .build() signUpRequest = BeginSignInRequest.builder() .setGoogleIdTokenRequestOptions( BeginSignInRequest.GoogleIdTokenRequestOptions.builder() .setSupported(true) .setServerClientId(getString(R.string.firebase_client_id)) .setFilterByAuthorizedAccounts(false) .build()) .build() setContent { val authViewModel: LoginViewModel = viewModel() val authState = authViewModel.viewstate.collectAsState().value LoginScreen( activity, oneTapClient, signInRequest, signUpRequest, authViewModel, auth) } } } } @OptIn(ExperimentalMaterial3Api::class) @Composable fun LoginScreen( activity: Activity, oneTapClient: SignInClient, signInRequest: BeginSignInRequest, signUpRequest: BeginSignInRequest, loginViewModel: LoginViewModel, auth: FirebaseAuth, ) { val launcher = rememberLauncherForActivityResult( ActivityResultContracts.StartIntentSenderForResult() ) { result -> if (result.resultCode == RESULT_OK) { val credential = oneTapClient.getSignInCredentialFromIntent(result.Data) val idToken = credential.googleIdToken if (idToken != null) { // Got an ID token from Google. Use it to authenticate // with your backend. when { idToken != null -> { // Got an ID token from Google. Use it to authenticate // with Firebase. val firebaseCredential = getCredential(idToken, null) auth.signInWithCredential(firebaseCredential) .addOnCompleteListener(activity) { task -> if (task.isSuccessful) { // Sign in success, update UI with the signed-in user's information Log.d(TAG_FIREBASE, "signInWithCredential:success") val user = auth.currentUser } else { // If sign in fails, display a message to the user. Log.w(TAG_FIREBASE, "signInWithCredential:failure", task. Exception) } } } else -> { // Shouldn't happen. Log.d(TAG_GOOGLE, "No ID token!") } } Log.d("LOG", idToken) } else { Log.d("LOG", "Null Token") } } else { Log.e("Response", "${result.resultCode}") } } Material3AppTheme() { Scaffold { padding -> padding Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { val scope = rememberCoroutineScope() Surface( onClick = { scope.launch { loginViewModel.signIn(activity, oneTapClient, signInRequest, signUpRequest, launcher) } }, color = MaterialTheme.colorScheme.onPrimary, shadowElevation = 0.dp, shape = RoundedCornerShape(5.dp), border = BorderStroke(width = 1.dp, color = MaterialTheme.colorScheme.primaryContainer), ) { Row( modifier = Modifier .padding( start = 12.dp, end = 16.dp, ), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center, ) { Icon( painter = painterResource(id = R.drawable.ic_google_logo), contentDescription = "SignInButton", tint = androidx.compose.ui.graphics.Color.Unspecified, ) Text(text = "Sign in with Google") } } } } } }
LoginViewModel.kt
fun signIn( activity: Activity, oneTapClient: SignInClient, signInRequest: BeginSignInRequest, signUpRequest: BeginSignInRequest, launcher: ActivityResultLauncher<IntentSenderRequest>, ) { oneTapClient.beginSignIn(signInRequest) .addOnSuccessListener(activity) { result -> try { val intentSenderRequest = IntentSenderRequest.Builder(result.pendingIntent.intentSender).build() launcher.launch(intentSenderRequest) Log.d(TAG_SIGNIN, "Started One Tap Sign In") } catch (e: IntentSender.SendIntentException) { Log.e(TAG_SIGNIN, "Couldn't start One Tap UI: ${e.localizedMessage}") } } .addOnFailureListener(activity) { e -> e.localizedMessage?.let { Log.d(TAG_SIGNUP, "$it: non functional") } oneTapClient.beginSignIn(signUpRequest) .addOnSuccessListener(activity) { result -> try { val intentSenderRequest = IntentSenderRequest.Builder(result.pendingIntent.intentSender).build() launcher.launch(intentSenderRequest) } catch (e: IntentSender.SendIntentException) { Log.e(TAG_SIGNUP, "Couldn't start One Tap UI: ${e.localizedMessage}") } } .addOnFailureListener(activity) { e -> // No Google Accounts found. Just continue presenting the signed-out UI. e.localizedMessage?.let { Log.d(TAG_SIGNUP, "$it: even less non functional") } } } }
排查与修复方案
代码细节修正
- 回调中
result.Data应为result.data(小写d),这是导致空指针的直接原因,修正后可正常获取凭证:val credential = oneTapClient.getSignInCredentialFromIntent(result.data) - 检查
viewModel中TAG_SIGNIN、TAG_SIGNUP是否已正确定义,避免日志缺失。
- 回调中
配置信息校验
- 确认Firebase控制台的Web类型
OAuth 2.0 客户端ID已正确填入strings.xml的firebase_client_id字段。 - 检查Google Play Console中应用的
SHA-1和SHA-256指纹,已同步到Firebase项目设置(两种指纹都需添加)。 - 确认Firebase控制台
Authentication模块已启用Google登录提供商。
- 确认Firebase控制台的Web类型
设备与环境检查
- 测试设备需登录有效Google账号,且Google Play服务为最新版本。
- 优先使用真机测试,部分模拟器的Google服务存在兼容性问题。
- 清除应用缓存后重新测试,避免旧配置残留。
权限与签名验证
- 应用签名配置(debug/release)需与Firebase中添加的指纹完全匹配,debug包用debug指纹,release包用release指纹。
- 确保
AndroidManifest.xml添加了必要权限:<uses-permission android:name="android.permission.INTERNET" />
内容的提问来源于stack exchange,提问作者ibbs
相关产品推荐
相关产品推荐

