React Native/Expo中Google选账户后认证报错求助
React Native Expo Google登录失败问题排查与解决
可能的原因及对应修复方案
1. Google Cloud控制台配置错误
- 客户端ID不匹配:你代码中
androidClientId和clientId使用相同值是错误的。需分别配置:clientId:使用Google Cloud中创建的Web应用客户端IDandroidClientId:使用Google Cloud中创建的Android应用客户端ID(包名填host.exp.exponent,签名证书指纹用Expo默认值:SHA-1: BB:0D:AC:74:D3:21:E1:43:67:71:9B:62:91:AF:A1:66:6E:44:5D:75,或自定义构建的指纹)
- 重定向URI未配置:即使启用
useProxy,仍需在Google Cloud的OAuth客户端配置中添加Expo的重定向URI。运行项目后,打印redirectUri的值,将其添加到"已授权的重定向URI"列表中 - OAuth同意屏幕未配置测试用户:未发布的OAuth应用仅允许添加的测试用户登录,需在Google Cloud控制台的"OAuth同意屏幕"中添加你的测试邮箱
2. Expo Auth Session配置缺失
- 未请求必要权限:默认的Google登录请求未包含
email和profile权限,导致无法获取有效id_token。需在useAuthRequest中添加scopes:const [request, , promptAsync] = Google.useAuthRequest({ clientId: '你的Web客户端ID', androidClientId: '你的Android客户端ID', redirectUri: redirectUri, scopes: ['profile', 'email'], // 添加权限范围 });
3. Firebase与本地后端问题
- Firebase Google登录未启用:需在Firebase控制台的"Authentication"->"登录方法"中启用Google登录,并填入正确的Web客户端ID
- 本地后端访问失败:Android模拟器无法通过
0.0.0.0访问本地服务,需将fetch的URL改为http://10.0.2.2:3000/auth/google
关键调试步骤
- 打印完整登录结果:在
handleGoogleLogin中,无论登录成功与否,都打印完整的result对象,获取错误详情:const result = await promptAsync(); console.log('登录结果详情:', result); if (result.type !== 'success') return; - 验证id_token有效性:拿到
id_token后,用Google的TokenInfo接口验证(直接在浏览器访问):
检查返回的用户信息是否正确,是否存在权限不足的提示https://oauth2.googleapis.com/tokeninfo?id_token=你的id_token值 - 查看官方日志:
- Google Cloud控制台:
APIs & Services->OAuth同意屏幕->查看日志,获取OAuth流程的错误日志 - Firebase控制台:
Authentication->日志,查看登录失败的具体原因
- Google Cloud控制台:
- 打印完整错误对象:在catch块中打印完整错误,而不仅仅是message:
catch (error: any) { console.log('完整错误信息:', error); alert('Erro ao fazer login com Google.'); }
修正后的核心代码示例
export default function RegisterScreen({navigation}: { navigation: any }) { const redirectUri = makeRedirectUri({ useProxy: true, }); console.log('当前重定向URI:', redirectUri); // 打印用于配置Google Cloud const [request, , promptAsync] = Google.useAuthRequest({ clientId: '你的Web客户端ID', androidClientId: '你的Android客户端ID', redirectUri: redirectUri, scopes: ['profile', 'email'], }); const handleGoogleLogin = async () => { try { const result = await promptAsync(); console.log('登录结果:', result); if (result.type !== 'success') { console.log('登录失败原因:', result.type, result.params); return; } const { id_token } = result.params; const credential = GoogleAuthProvider.credential(id_token); const userCredential = await signInWithCredential(auth, credential); const user = userCredential.user; // 修正Android模拟器的后端地址 const response = await fetch('http://10.0.2.2:3000/auth/google', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ uid: user.uid, nome: user.displayName, email: user.email, foto: user.photoURL, }), }); const data = await response.json(); console.log('Google Login OK:', data); await AsyncStorage.setItem('token', data.token); await AsyncStorage.setItem('nome', data.nome ?? ''); await AsyncStorage.setItem('foto', data.foto ?? ''); alert(`Bem-vindo, ${data.nome}! ✅`); navigation.navigate('Início'); } catch (error: any) { console.log('完整错误:', error); alert('Erro ao fazer login com Google.'); } }; // 其他组件代码... }
内容的提问来源于stack exchange,提问作者KevinGuedes
相关产品推荐
相关产品推荐

