使用Firebase实现用户登录时持续触发ApiException:8错误排查
Firebase Google登录ApiException:8 问题排查与解决
我在实现Firebase Google登录功能时,始终触发ApiException:8错误,已排查多项常见问题仍未解决,恳请帮忙分析原因并提供解决办法。
已完成的排查项
- google-services.json文件已被正确识别
- 各项值/ID与Firebase项目配置完全匹配
- 模拟器设备已登录个人Gmail账号
- 网络连接正常
- 已将~/.android/debug.keystore中的SHA-1和SHA-256添加至Firebase
- 已执行重建/清理缓存操作
登录方法代码
private fun signIn() { val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build() val googleSignInClient = GoogleSignIn.getClient(this, gso) val signInIntent = googleSignInClient.signInIntent val task = GoogleSignIn.getSignedInAccountFromIntent(signInIntent) try { val auth = Firebase.auth // Authenticate with Firebase using Google credentials val account = task.getResult(ApiException::class.java) val credential = GoogleAuthProvider.getCredential(account?.idToken, null) auth.signInWithCredential(credential) .addOnCompleteListener(this) { task -> if (task.isSuccessful) { // User is logged in, obtain JWT token and return to calling activity val user = auth.currentUser user?.getIdToken(true)?.addOnSuccessListener { result -> val token = result.token val resultIntent = Intent() Timber.i(String.format("Logged in; Token %s", token)) resultIntent.putExtra("jwt_token", token) setResult(Activity.RESULT_OK, resultIntent) finish() } } else { // Authentication failed, show error message Toast.makeText(this, "Authentication failed.", Toast.LENGTH_SHORT).show() } } } catch (e: ApiException) { Timber.e(e); // Google Sign-In failed, show error message Toast.makeText(this, "Google sign-in failed.", Toast.LENGTH_SHORT).show() } }
错误日志
com.google.android.gms.common.api.ApiException: 8: at com.google.android.gms.common.internal.ApiExceptionUtil.fromStatus(com.google.android.gms:play-services-base@@18.0.1:3) at com.google.android.gms.auth.api.signin.GoogleSignIn.getSignedInAccountFromIntent(com.google.android.gms:play-services-auth@@20.5.0:3) at com.myapp.android.LoginActivity.signIn(LoginActivity.kt:45) at com.myapp.android.LoginActivity.onCreate$lambda$0(LoginActivity.kt:32)
App模块build.gradle配置
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'com.google.gms.google-services' } android { namespace 'com.myapp.android' compileSdk 33 defaultConfig { applicationId "com.myapp.android" minSdk 26 targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary true } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } buildFeatures { compose true } composeOptions { kotlinCompilerExtensionVersion '1.4.0' } packagingOptions { resources { excludes += '/META-INF/{AL2.0,LGPL2.1}' } } } dependencies { // Firebase implementation platform('com.google.firebase:firebase-bom:31.5.0') implementation 'com.google.firebase:firebase-auth-ktx' implementation 'com.google.android.gms:play-services-auth:20.5.0' // Logging implementation 'com.jakewharton.timber:timber:5.0.1' implementation 'androidx.core:core-ktx:1.10.0' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' implementation 'androidx.activity:activity-compose:1.7.1' implementation platform('androidx.compose:compose-bom:2022.10.00') implementation 'androidx.compose.ui:ui' implementation 'androidx.compose.ui:ui-graphics' implementation 'androidx.compose.ui:ui-tooling-preview' implementation 'androidx.compose.material3:material3' implementation 'androidx.core:core-ktx:1.10.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00') androidTestImplementation 'androidx.compose.ui:ui-test-junit4' debugImplementation 'androidx.compose.ui:ui-tooling' debugImplementation 'androidx.compose.ui:ui-test-manifest' }
项目根目录build.gradle配置
buildscript { ext { kotlin_version = '1.8.0' } repositories { // Make sure that you have the following two repositories google() // Google's Maven repository mavenCentral() // Maven Central repository } dependencies { // Add the dependency for the Google services Gradle plugin classpath 'com.google.gms:google-services:4.3.15' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { id 'com.android.application' version '8.0.0' apply false id 'com.android.library' version '8.0.0' apply false id 'org.jetbrains.kotlin.android' version '1.8.0' apply false }
问题原因与解决办法
ApiException:8对应SIGN_IN_FAILED,核心问题出在登录流程的实现逻辑错误:
1. 错误核心点
当前代码直接创建signInIntent后就调用GoogleSignIn.getSignedInAccountFromIntent(signInIntent),但这个方法是用来处理登录返回结果的,而非直接触发登录。正确流程应该是启动登录Activity获取返回结果,再在回调中处理返回的Intent。
2. 修复后的代码实现
方案一:使用ActivityResultLauncher(推荐,适配Jetpack Compose)
// 在Activity的onCreate中初始化Launcher private val googleSignInLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { val task = GoogleSignIn.getSignedInAccountFromIntent(result.data) try { val account = task.getResult(ApiException::class.java) val credential = GoogleAuthProvider.getCredential(account?.idToken, null) Firebase.auth.signInWithCredential(credential) .addOnCompleteListener(this) { authTask -> if (authTask.isSuccessful) { val user = Firebase.auth.currentUser user?.getIdToken(true)?.addOnSuccessListener { tokenResult -> val token = tokenResult.token val resultIntent = Intent() Timber.i("Logged in; Token %s", token) resultIntent.putExtra("jwt_token", token) setResult(Activity.RESULT_OK, resultIntent) finish() } } else { Toast.makeText(this, "Authentication failed.", Toast.LENGTH_SHORT).show() } } } catch (e: ApiException) { Timber.e(e) Toast.makeText(this, "Google sign-in failed.", Toast.LENGTH_SHORT).show() } } } // 修改signIn方法 private fun signIn() { val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build() val googleSignInClient = GoogleSignIn.getClient(this, gso) googleSignInLauncher.launch(googleSignInClient.signInIntent) }
方案二:传统onActivityResult方式
private fun signIn() { val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build() val googleSignInClient = GoogleSignIn.getClient(this, gso) startActivityForResult(googleSignInClient.signInIntent, RC_SIGN_IN) } companion object { private const val RC_SIGN_IN = 1001 } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == RC_SIGN_IN) { val task = GoogleSignIn.getSignedInAccountFromIntent(data) try { val account = task.getResult(ApiException::class.java) val credential = GoogleAuthProvider.getCredential(account?.idToken, null) Firebase.auth.signInWithCredential(credential) .addOnCompleteListener(this) { authTask -> if (authTask.isSuccessful) { val user = Firebase.auth.currentUser user?.getIdToken(true)?.addOnSuccessListener { tokenResult -> val token = tokenResult.token val resultIntent = Intent() Timber.i("Logged in; Token %s", token) resultIntent.putExtra("jwt_token", token) setResult(Activity.RESULT_OK, resultIntent) finish() } } else { Toast.makeText(this, "Authentication failed.", Toast.LENGTH_SHORT).show() } } } catch (e: ApiException) { Timber.e(e) Toast.makeText(this, "Google sign-in failed.", Toast.LENGTH_SHORT).show() } } }
3. 额外验证项
- 确认
default_web_client_id是Firebase控制台中Web应用的客户端ID,而非Android应用的客户端ID - 检查Firebase控制台中是否启用了Google登录提供商(Authentication > Sign-in method > Google > 启用)
- 若使用模拟器,确保Google Play服务版本是最新的,可通过Google Play商店更新
内容的提问来源于stack exchange,提问作者Stefan Falk
相关产品推荐
相关产品推荐

