Jetpack Compose中Google登录ActivityResultLauncher返回RESULT_CANCELED
Jetpack Compose Google登录回调始终返回RESULT_CANCELED的解决方案
问题排查与修复步骤
1. 确认Google Sign-In Client ID类型正确
在GoogleAuthSignInClient的generateSignInRequest方法中,setServerClientId必须传入Web应用的Client ID,而非Android客户端ID:
- 打开Firebase控制台 → 项目设置 → 常规 → 找到"Web应用"板块,复制对应Client ID
- 将
strings.xml中的firebase_client_id替换为该Web Client ID
2. 将ActivityResultLauncher移至Activity层级
当前你将googleSignInLauncher放在Composable内部,NavHost的导航重组可能导致Launcher状态异常。建议移至Activity类中:
class LoginAndRegistrationActivity : ComponentActivity() { private val viewModel: GoogleSignInViewModel by viewModels() private val googleAuthSignInClient by lazy { GoogleAuthSignInClient( context = this, oneTapClient = Identity.getSignInClient(this) ) } // 移至Activity层面,避免Composable重组影响 private val googleSignInLauncher = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result -> if (result.resultCode == RESULT_OK) { result.data?.let { intent -> lifecycleScope.launch { val signInResult = googleAuthSignInClient.signInWithIntent(intent) viewModel.onSignInResult(signInResult) } } } else { Log.e("GoogleSignIn", "回调取消,状态码: ${result.resultCode}") val exception = result.data?.getSerializableExtra( ActivityResultContracts.StartIntentSenderForResult.EXTRA_SEND_INTENT_EXCEPTION, Exception::class.java ) exception?.printStackTrace() } } @RequiresApi(Build.VERSION_CODES.TIRAMISU) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { PokidexAppTheme { val navHostController = rememberNavController() if (googleAuthSignInClient.getSignedInUser() != null) { startActivity(Intent(this, HomeActivity::class.java)) } NavHost(navController = navHostController, startDestination = "register_home") { composable(route = "register_home") { val loginState = viewModel.loginState.collectAsState() LaunchedEffect(key1 = loginState.value.isSignSuccessful) { if(loginState.value.isSignSuccessful) { Toast.makeText( this@LoginAndRegistrationActivity, "Google登录成功", Toast.LENGTH_LONG ).show() startActivity(Intent(this@LoginAndRegistrationActivity, HomeActivity::class.java)) viewModel.resetState() } else if (!loginState.value.errorMessage.isNullOrEmpty()) { Toast.makeText( this@LoginAndRegistrationActivity, loginState.value.errorMessage, Toast.LENGTH_LONG ).show() } } RegistrationHomePage( onNavigationClick = { navHostController.navigateUp() }, registerWithEmailClick = { navHostController.navigate("email_reg") { launchSingleTop = true } }, registerWithGoogleClick = { lifecycleScope.launch { val googleSignIn = googleAuthSignInClient.signIn() googleSignIn?.let { intentSender -> try { googleSignInLauncher.launch( IntentSenderRequest.Builder(intentSender).build() ) } catch (e: Exception) { e.printStackTrace() } } } } ) } // 其余Composable保持不变 } } } } }
3. 配置正确的SHA-1指纹
- 在Android Studio右侧Gradle面板 → 你的项目 → Tasks → android → signingReport,复制debug和release版本的SHA-1指纹
- 打开Firebase控制台 → 项目设置 → 常规 → 应用板块,点击"添加指纹",粘贴SHA-1并保存
4. 验证OAuth同意表单配置
- 打开Google Cloud Console → 你的项目 → API和服务 → OAuth同意屏幕
- 确保已添加
email、profile、openid必要范围 - 若处于测试状态,确认使用的Google账号已加入测试用户列表
5. 增强错误日志输出
修改GoogleAuthSignInClient的signInWithIntent方法,添加详细日志便于排查:
suspend fun signInWithIntent(intent: Intent): GoogleSignInResult { return try { val credential = oneTapClient.getSignInCredentialFromIntent(intent) Log.d("GoogleSignIn", "获取到凭证: ${credential.id}") val googleIdToken = credential.googleIdToken if (googleIdToken.isNullOrEmpty()) { Log.e("GoogleSignIn", "Google ID Token为空") return GoogleSignInResult(errorMessage = "获取Google ID Token失败") } val googleCredentials = GoogleAuthProvider.getCredential(googleIdToken, null) val authResult = firebaseAuth.signInWithCredential(googleCredentials).await() authResult.user?.let { user -> Log.d("GoogleSignIn", "登录成功,用户: ${user.displayName}") GoogleSignInResult( googleUserData = UserData( userId = user.uid, userName = user.displayName, profileImageUrl = user.photoUrl?.toString() ) ) } ?: run { Log.e("GoogleSignIn", "认证结果无用户信息") GoogleSignInResult(errorMessage = "登录失败: 无用户返回") } } catch (e: Exception) { Log.e("GoogleSignIn", "登录异常", e) if (e is CancellationException) throw e GoogleSignInResult(errorMessage = e.message ?: "未知登录错误") } }
6. 调整BeginSignInRequest配置
暂时关闭自动选择功能,避免潜在冲突:
private fun generateSignInRequest() = BeginSignInRequest.builder() .setGoogleIdTokenRequestOptions( BeginSignInRequest.GoogleIdTokenRequestOptions.builder() .setSupported(true) .setServerClientId(context.getString(R.string.firebase_client_id)) .setFilterByAuthorizedAccounts(false) .build() ) .setAutoSelectEnabled(false) .build()
内容的提问来源于stack exchange,提问作者Siddhartha Nowal
相关产品推荐
相关产品推荐

