Android集成Google Sign-In API首次登录遇12501错误求助
问题分析与修复方案
核心问题定位
- ActivityLauncher变量不匹配:你注册的登录结果回调是
googleRegistry,但实际启动登录Intent用的是googleDefaultLauncher,导致首次登录的结果无法被正确接收处理,看起来无响应;第二次Google已缓存账号状态,直接静默登录成功。 - 未处理任务失败场景:回调中直接强制解包
task.result!!,当返回12501(用户取消登录)时会抛出异常,中断后续逻辑,用户看不到任何反馈。 - 异步操作中不安全访问
auth.currentUser:signInWithCredential是异步方法,未完成时auth.currentUser可能为空,触发空指针异常。
代码修复步骤
1. 修正ActivityLauncher引用
确保启动登录Intent的是你注册的回调实例,修改defaultGoogleLogin方法:
fun defaultGoogleLogin(cxt: Context, launcher: ActivityResultLauncher<Intent>) { val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestProfile() .requestEmail() .requestIdToken(cxt.getString(R.string.google_client_id)) .build() mGoogleSignInClient = GoogleSignIn.getClient(cxt, gso) val signInIntent = mGoogleSignInClient.signInIntent launcher.launch(signInIntent) }
点击事件调用时传入正确的Launcher:
googleLogin.setOnClickListener{ firebaseAuthUtil.defaultGoogleLogin(this, googleRegistry) }
2. 完善登录结果回调的错误处理
避免强制解包,先判断任务是否成功:
val googleRegistry = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result -> val task = GoogleSignIn.getSignedInAccountFromIntent(result.data) getSharedPreferences(SHARED_PREF, MODE_PRIVATE).edit().putBoolean(GOOGLE_TAP_SIGNIN,true).apply() if (task.isSuccessful) { val account = task.result Log.d("LogINActivity","email: ${account?.email}") firebaseAuthUtil.handleSignInResult(this, task) } else { val exception = task.exception as? ApiException Log.w("Google", "signInResult:failed code=${exception?.statusCode}") Toast.makeText(this, "登录取消或失败", Toast.LENGTH_SHORT).show() } }
3. 修复异步登录后的用户信息更新
在signInWithCredential的回调里先验证登录成功,再安全访问当前用户:
fun handleSignInResult(cxt: Context, task: Task<GoogleSignInAccount>) { try { Log.d("FirebaseAuthUtil","HandleSignINResult") val account: GoogleSignInAccount = task.getResult(ApiException::class.java) auth.signInWithCredential(GoogleAuthProvider.getCredential(account.idToken,null)) .addOnCompleteListener { authTask -> if (authTask.isSuccessful) { val currentUser = auth.currentUser ?: return@addOnCompleteListener val updateProfile = UserProfileChangeRequest.Builder() .setPhotoUri(account.photoUrl) .setDisplayName(account.displayName) .build() currentUser.updateProfile(updateProfile) .addOnFailureListener { Toast.makeText(cxt, "头像更新失败", Toast.LENGTH_SHORT).show() } if (currentUser.email != account.email) { currentUser.updateEmail(account.email!!) .addOnFailureListener { Toast.makeText(cxt, "邮箱更新失败", Toast.LENGTH_SHORT).show() } } } else { Toast.makeText(cxt, "Firebase登录失败", Toast.LENGTH_SHORT).show() } } } catch (e: ApiException) { Log.w("Google", "signInResult:failed code=${e.statusCode} message=${e.message}") Toast.makeText(cxt, "Google登录失败:${e.localizedMessage}", Toast.LENGTH_SHORT).show() } catch (e1: IllegalArgumentException) { Toast.makeText(cxt,"抱歉,无法使用Google账号登录",Toast.LENGTH_SHORT).show() } }
4. 额外优化:复用GoogleSignInClient
不需要每次点击都重新创建客户端,初始化时构建一次即可:
class FirebaseAuthUtil(private val context: Context) { private val mGoogleSignInClient: GoogleSignInClient init { val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestProfile() .requestEmail() .requestIdToken(context.getString(R.string.google_client_id)) .build() mGoogleSignInClient = GoogleSignIn.getClient(context, gso) } fun defaultGoogleLogin(launcher: ActivityResultLauncher<Intent>) { val signInIntent = mGoogleSignInClient.signInIntent launcher.launch(signInIntent) } // 其他方法... }
验证修复
- 首次点击登录,选择邮箱后会正确进入回调流程,取消登录也会弹出提示。
- 登录成功后,用户信息会正确同步到Firebase。
- 第二次点击登录时,若账号已缓存,会直接完成登录流程。
内容的提问来源于stack exchange,提问作者moumenShobakey
相关产品推荐
相关产品推荐

