Expo Go集成Google Firebase登录遇400错误:重定向URL异常
解决Expo Go中Google认证Error 400: invalid_request问题
问题核心
你遇到的invalid_request错误,根源是重定向地址不匹配:Expo Go调试时默认使用本地exp://地址,但该地址未在Google Cloud Console中授权,同时你可能错误配置了Android客户端的包名(使用自定义项目包名而非Expo Go官方包名)。
解决方案
1. 修正Google Cloud Console的客户端配置
Android客户端(适配Expo Go)
- 删除现有Android客户端,重新创建:
- 包名填写:
host.exp.exponent(Expo Go的官方包名) - SHA-1指纹填写Expo官方默认值:
BB:0D:AC:74:D3:21:E1:43:67:71:9B:62:91:AF:A1:66:6E:44:5D:75,或通过expo credentials:manager命令获取当前环境的SHA-1
- 包名填写:
Web客户端
在现有Web客户端的Authorized redirect URIs中添加两个地址:
https://auth.expo.io/@gpocil/GourmAI(你的Expo Auth固定重定向地址)- 报错中显示的本地地址
exp://192.168.1.40:8081(临时适配调试环境,IP变化后需更新)
2. 代码中明确指定重定向地址
修改Google.useAuthRequest的配置,添加redirectUri参数锁定Expo Auth地址:
const config = { androidClientId: '替换为新创建的Expo Go Android客户端ID', webClientId: '你的Web客户端ID', redirectUri: 'https://auth.expo.io/@gpocil/GourmAI', // 新增该行 };
3. 清理缓存并重启
- 清除AsyncStorage缓存:可临时添加测试按钮执行
AsyncStorage.clear(),或卸载重装Expo Go - 重启Expo开发服务器和Expo Go应用
修改后的完整代码
import React, { useState, useEffect } from 'react'; import { Button, View, Text, StyleSheet } from 'react-native'; import * as WebBrowser from 'expo-web-browser'; import * as Google from 'expo-auth-session/providers/google'; import AsyncStorage from '@react-native-async-storage/async-storage'; WebBrowser.maybeCompleteAuthSession(); export default function Login() { const [userInfo, setUserInfo] = useState(null); const config = { androidClientId: '替换为新创建的Expo Go Android客户端ID', webClientId: '你的Web客户端ID', redirectUri: 'https://auth.expo.io/@gpocil/GourmAI', }; const [request, response, promptAsync] = Google.useAuthRequest(config); useEffect(() => { signInWithGoogle(); }, [response]); const getUserInfo = async (token) => { if (!token) return; try { const response = await fetch("https://www.googleapis.com/userinfo/v2/me", { headers: { Authorization: `Bearer ${token}` }, }); const user = await response.json(); await AsyncStorage.setItem("user", JSON.stringify(user)); setUserInfo(user); } catch (error) { console.error("Failed to fetch user data:", error); } }; const signInWithGoogle = async () => { try { const userJSON = await AsyncStorage.getItem("user"); if (userJSON) { setUserInfo(JSON.parse(userJSON)); } else if (response?.type === "success") { getUserInfo(response.authentication.accessToken); } } catch (error) { console.error("Error retrieving user data from AsyncStorage:", error); } }; return ( <View style={styles.container}> <Button disabled={!request} title="Sign in with Google" onPress={() => promptAsync()} /> {userInfo && ( <Text style={styles.userInfo}> Logged in as: {userInfo.name} </Text> )} </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#fff', }, userInfo: { marginTop: 20, fontSize: 16, }, });
内容的提问来源于stack exchange,提问作者P.O .Causs
相关产品推荐
相关产品推荐

