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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:33:15