上线后Google Sign In异常,报ApiException:10错误求助
Google Sign In 切换 OAuth 到生产环境后报错 ApiException:10 的排查与解决
问题背景
将 Google Cloud Console 中的 OAuth 屏幕从测试环境切换到生产环境后,Google SignIn 完全无法正常工作,抛出错误:
I/flutter (25941): Error PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , null, null)
用户点击按钮触发_handleSignIn,应用重启时调用_attemptSignInSilently,若本地存储的isLoggedIn为true则自动跳转主页,目前完全无法登录。
我的 Flutter 代码
//Google Config GoogleSignIn _googleSignIn = GoogleSignIn( scopes: scopes, ); const List<String> scopes = <String>[ 'openid', // 'email', // 'profile', ]; @override void initState() { super.initState(); _attemptSignInSilently(); } void _attemptSignInSilently() async { String? isLoggedIn = await storage.read(key: 'isLoggedIn'); if (isLoggedIn == 'true') { try { GoogleSignInAccount? account = await _googleSignIn.signInSilently(); if (account == null) { await _handleSignIn(); } else { final googleSignInAuthentication = await account.authentication; bool token_verified = await send_Auth(googleSignInAuthentication.idToken); if (token_verified) { google_Login(account.email, context, token_verified); } else {} } } catch (error) {} } } //Send User Data to Backend Future<bool> send_Auth(String? token) async { try { if (token == null) { return false; } final response = await http.post( Uri.parse('${dotenv.env['baseUrl']}/auth_googleEndpoint'), headers: <String, String>{ 'Content-Type': 'application/json; charset=UTF-8', }, body: jsonEncode(<String, String>{ 'idToken': token, }), ); if (response.statusCode == 200) { return true; } else { return false; } } catch (error) {} return false; } //Handle Sign In - Sign Out Future<void> _handleSignIn() async { try { await _googleSignIn.signOut(); // await _googleSignIn.requestScopes(scopes); // await _googleSignIn.canAccessScopes(scopes); GoogleSignInAccount? account = await _googleSignIn.signIn(); if (account == null) { return null; } final googleSignInAuthentication = await account.authentication; bool token_verified = await send_Auth(googleSignInAuthentication.idToken); if (token_verified) { google_Login(account.email, context, token_verified); } else {} } catch (error) { print("Error ${error}"); } } Future<void> handleSignOut() async { try { await _googleSignIn.disconnect(); await _googleSignIn.signOut(); } catch (error) {} }
build.gradle 配置
signingConfigs { debug { keyAlias keystoreProperties['keyAlias2'] keyPassword keystoreProperties['keyPassword2'] storeFile keystoreProperties['storeFile2'] ? file(keystoreProperties['storeFile2']) : null storePassword keystoreProperties['storePassword2'] } release { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null storePassword keystoreProperties['storePassword'] } } buildTypes { debug { signingConfig signingConfigs.debug signingConfig signingConfigs.release } release { signingConfig signingConfigs.debug signingConfig signingConfigs.release //minifyEnabled true } } }
其中keyAlias是应用正式签名,keyAlias2是 Google SignIn 测试用的 jks 文件。
问题排查与解决方案
1. ApiException:10 的核心原因
这个错误绝大多数是签名证书的 SHA-1/SHA-256 未在 Google Cloud Console 正确配置,切换生产环境后必须确保:
- 生产签名证书的哈希值已添加到 OAuth 2.0 客户端ID配置中
- 测试签名的哈希值如果需要保留调试用,也得正确配置
2. build.gradle 配置的明显错误
你的 buildTypes 里给每个构建类型同时设置了两个 signingConfig,后面的配置会直接覆盖前面的:
- debug 构建实际用的是 release 签名
- release 构建也用的是 release 签名
这会导致本地调试时使用生产签名,如果 Google Cloud 里只配置了测试签名的哈希,必然报错。而且你明确说明keyAlias2是测试用的 Google SignIn jks,现在完全没用到。
修复方法:
修改 buildTypes 为单一正确配置:
buildTypes { debug { signingConfig signingConfigs.debug // 用测试jks(keyAlias2对应的配置) } release { signingConfig signingConfigs.release // 用正式应用签名(keyAlias对应的配置) } }
3. Google Cloud Console 配置检查
- 进入 Google Cloud Console → API 和服务 → 凭据 → 找到你的 Android 类型 OAuth 2.0 客户端ID
- 确认已添加debug 和 release 两种签名的 SHA-1/SHA-256 哈希值
- 确认 OAuth 同意屏幕已切换为“已发布”状态,且完成所有必要验证(针对外部用户类型)
- 核对客户端ID与 Flutter 项目中
google-services.json里的配置一致
4. 代码层面的优化建议
- 打开
email和profile权限,Google SignIn 部分场景需要这些基础权限才能正常获取用户信息 _attemptSignInSilently的 catch 块不要吞掉错误,添加打印方便调试:catch (error) {print("静默登录错误: $error");}_handleSignIn里先 signOut 再 signIn 的逻辑会强制用户每次重新选账号,可根据产品需求调整
内容的提问来源于 stack exchange,提问作者 Thanos Rom
相关产品推荐
相关产品推荐

