Expo-auth-session在Android独立应用中无法完成Google登录问题
Expo React Native Android独立应用Google登录无响应问题解决
问题现象
基于Expo开发的React Native应用,使用expo-auth-session/providers/google实现Google登录功能,在Expo开发环境中运行正常,但构建为Android独立应用后,点击登录按钮无任何响应。
核心修复方案
1. 修正函数拼写错误
代码中promtAsync为拼写错误,正确应为promptAsync,这是导致点击无响应的直接原因:
// 原错误代码 const [req, res, promtAsync] = Google.useIdTokenAuthRequest(...) // 修正后 const [req, res, promptAsync] = Google.useIdTokenAuthRequest(...) // 调用时同步修正 const onLogin = () => promptAsync() .then((response) => { // 后续逻辑保持不变 })
2. 完善Android回调配置
在app.json的android字段中添加intentFilters,确保登录回调能正确跳转回应用,scheme需与根字段的scheme保持一致:
"android": { "package": "com.xxx.xx", "versionCode": 1, "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#FFFFFF" }, "intentFilters": [ { "action": "VIEW", "data": [ { "scheme": "com.xxx.xx" } ], "category": [ "BROWSABLE", "DEFAULT" ] } ] }
3. 调整回调处理位置
将WebBrowser.maybeCompleteAuthSession()移至App入口文件(如App.js)顶部,避免页面焦点变化导致回调丢失:
// App.js 顶部 import * as WebBrowser from 'expo-web-browser'; WebBrowser.maybeCompleteAuthSession();
4. 验证Google Cloud配置
- 确保
ANDROID_CLIENT_ID是Google Cloud控制台中为Android应用创建的OAuth 2.0客户端ID,格式为{数字}-{字符串}.apps.googleusercontent.com - 客户端ID配置的包名需与
app.json中android.package完全一致 - 已添加独立应用构建使用的Keystore SHA-1指纹到Google Cloud的客户端ID配置中
附:用户提供的原始代码与配置
AuthScreen原始代码
... import decode from 'jwt-decode'; import { ANDROID_CLIENT_ID, EXPO_CLIENT_ID, IOS_CLIENT_ID } from '../../env'; import * as Google from 'expo-auth-session/providers/google'; import * as WebBrowser from 'expo-web-browser'; ... import { useFocusEffect } from '@react-navigation/native'; ... WebBrowser.maybeCompleteAuthSession(); const AuthScreen = () => { const [isLoading, setIsLoading] = useState(false); const [isSigningIn, setIsSigningIn] = useState(false); // eslint-disable-next-line no-unused-vars const [req, res, promtAsync] = Google.useIdTokenAuthRequest({ expoClientId: EXPO_CLIENT_ID, androidClientId: ANDROID_CLIENT_ID, iosClientId: IOS_CLIENT_ID, scopes: ['profile', 'email'], }); const dispatch = useDispatch(); useFocusEffect( useCallback(() => { setIsLoading(true); loadFromStorage('user') .then(() => { setIsLoading(false); dispatch(setIsLoggedIn(true)); }) .catch(() => setIsLoading(false)); }, []), ); const onLogin = () => promtAsync() .then((response) => { console.log({ res, req }); if (response?.type === 'success') { const userInfo = decode(response?.params?.id_token); if (response?.params?.id_token) { setIsSigningIn(true); setIsLoading(true); login({ google_id_token: response?.params?.id_token, name: userInfo?.name, profile_image: userInfo?.picture, agent: Platform.OS, }) .then((res) => { const jwtToken = res?.headers?.['jwt-token']; saveToStorage({ key: 'jwtToken', value: jwtToken, }); saveToStorage({ key: 'user', value: userInfo }); setIsSigningIn(false); setIsLoading(false); dispatch(setIsLoggedIn(true)); }) .catch(() => { console.log('Unable to sign-in.'); setIsSigningIn(false); setIsLoading(false); }); } } }) .catch(() => { console.log('Unable to sign-in.'); setIsSigningIn(false); setIsLoading(false); }); return ( <View style={styles.container}> {isLoading ? ( <Loader /> ) : ( <> <ErpLogo /> <TouchableNativeFeedback onPress={onLogin}> <GoogleSignInButton style={styles.googleButton} /> </TouchableNativeFeedback> </> )} {isSigningIn && ( <Text style={{ position: 'absolute', bottom: Dimensions.get('screen').height / 30, fontFamily: fonts.firaSans400, color: colors.textColor, }} > Signing in... </Text> )} </View> ); }; export default AuthScreen;
app.json原始配置
{ "expo": { "name": "X", "slug": "x", "version": "1.0.0", "owner": "xyz", "orientation": "portrait", "icon": "./assets/img/erp.png", "userInterfaceStyle": "light", "scheme": "com.xxx.xx", "splash": { "image": "./assets/splash.png", "resizeMode": "contain", "backgroundColor": "#ffffff" }, "updates": { "fallbackToCacheTimeout": 0 }, "assetBundlePatterns": ["**/*"], "ios": { "supportsTablet": true, "bundleIdentifier": "com.xxx.xx", "buildNumber": "1.0.0" }, "android": { "package": "com.xxx.xx", "versionCode": 1, "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#FFFFFF" }, }, "web": { "favicon": "./assets/favicon.png" } } }
内容的提问来源于stack exchange,提问作者Hafiz Muhammad Bilal
相关产品推荐
相关产品推荐

