React Native Expo独立应用Google登录返回dismissed的原因排查
Expo独立应用Google登录返回dismissed的解决方法
针对你遇到的Expo Go中登录正常、独立应用打包后Google登录弹窗关闭返回dismissed的问题,按以下步骤排查解决:
核对Android应用的SHA-1指纹
独立应用的签名指纹和Expo Go完全不同,必须把打包用的指纹添加到Google开发者控制台的对应Android客户端中:- 若用Expo默认签名,执行命令:
expo fetch:android:hashes获取SHA-1和SHA-256指纹 - 若用自定义签名文件,用keytool生成指纹:
keytool -list -v -keystore your-keystore-file.jks
把获取到的指纹添加到Google控制台的Android应用配置里。
- 若用Expo默认签名,执行命令:
确认Client ID配置正确
代码中androidClientId必须是Google控制台中Android类型的客户端ID,不能混用Web类型的ID;独立应用可以移除expoClientId(该ID仅用于Expo Go环境),只保留androidClientId和webClientId(如果需要支持Web登录)。添加scheme配置
在app.json或app.config.js中添加scheme字段,比如:{ "expo": { "scheme": "yourappscheme" } }然后在Google控制台的Android客户端授权重定向URI中添加:
yourappscheme://oauthredirect调整promptAsync参数
独立应用是原生环境,不需要useProxy: true(该参数用于Expo Go/Web的代理跳转),可以简化promptAsync调用:promptAsync({ showInRecents: true })修改后的代码示例
import * as Google from 'expo-auth-session/providers/google'; import * as WebBrowser from 'expo-web-browser'; import React from "react"; import { View, Text, Button, StatusBar } from 'react-native'; interface User { name: string, email: string, picture: string, } export default function App() { const [accessToken, setAccessToken] = React.useState<string | null>(null); const [userInfo, setUserInfo] = React.useState<User | null>(null); const [txt, setTxt] = React.useState(""); WebBrowser.maybeCompleteAuthSession(); const [request, response, promptAsync] = Google.useAuthRequest({ androidClientId: '正确的Android客户端ID', webClientId: '正确的Web客户端ID' }); React.useEffect(() => { setTxt(response?.type || '') if(response?.type === "success") { setAccessToken(response.authentication!.accessToken); } }, [response]) const getUserInfo = async () => { if (!accessToken) return; const userInfoResponse = await fetch("https://www.googleapis.com/userinfo/v2/me", { headers: { Authorization: `Bearer ${accessToken}` } }); const userInfo = await userInfoResponse.json(); setUserInfo(userInfo); } const showUserInfo = () => { if (!userInfo) return null; return ( <View> <Text>姓名: {userInfo.name}</Text> <Text>邮箱: {userInfo.email}</Text> <Text>头像: {userInfo.picture}</Text> </View> ) } return ( <View style={{ flex:1, justifyContent:'center', alignItems:'center', gap:16 }}> <Text>{txt}</Text> {showUserInfo()} <Text>{accessToken}</Text> <Button title={accessToken ? "获取用户信息" : "登录"} onPress={accessToken ? getUserInfo : () => promptAsync({ showInRecents: true })} /> <StatusBar style="auto" /> </View> ); }
内容的提问来源于stack exchange,提问作者K. Gero
相关产品推荐
相关产品推荐

