React Native Expo AuthSession谷歌登录首次失效及警告问题排查
React Native Expo谷歌登录问题解决方案
一、首次登录无法获取用户信息的问题
问题原因
调用setGoogleAccessToken(authentication.accessToken)后,React的状态更新是异步操作,紧接着执行fetchUserInfo()时,googleAccessToken还未完成更新,导致fetchUserInfo内的if (googleAccessToken)条件不成立,无法发起用户信息请求。
解决方法
提供两种可行方案:
方案1:直接传递accessToken给请求函数
跳过状态依赖,直接将拿到的accessToken作为参数传入fetchUserInfo:
import * as React from "react"; import * as WebBrowser from "expo-web-browser"; import * as Google from "expo-auth-session/providers/google"; import { Button, View, Text } from "react-native"; WebBrowser.maybeCompleteAuthSession(); export default function LoginScreen() { const [googleAccessToken, setGoogleAccessToken] = React.useState(null); // 初始值改为null,更符合对象类型的判断逻辑 const [userInfo, setUserInfo] = React.useState(null); const [request, response, promptAsync] = Google.useAuthRequest({ expoClientId: "###", iosClientId: "###", androidClientId: "###", webClientId: "###", }); React.useEffect(() => { if (response?.type === "success") { const { authentication } = response; setGoogleAccessToken(authentication.accessToken); // 直接传入accessToken fetchUserInfo(authentication.accessToken); } }, [response]); // 修改函数,接收accessToken参数 const fetchUserInfo = (accessToken) => { fetch("https://www.googleapis.com/oauth2/v3/userinfo", { headers: { Authorization: `Bearer ${accessToken}` }, }) .then((response) => response.json()) .then((userInfoObj) => { setUserInfo(userInfoObj); console.log(userInfoObj); }) .catch((err) => { console.log(err); }); }; return ( <View> <Button disabled={!request} title="Login Here" onPress={() => { promptAsync(); }} /> {userInfo ? <Text>{userInfo.email}</Text> : <Text>Nope</Text>} </View> ); }
方案2:监听accessToken状态变化
新增useEffect监听googleAccessToken的更新,状态变化时自动触发用户信息请求:
import * as React from "react"; import * as WebBrowser from "expo-web-browser"; import * as Google from "expo-auth-session/providers/google"; import { Button, View, Text } from "react-native"; WebBrowser.maybeCompleteAuthSession(); export default function LoginScreen() { const [googleAccessToken, setGoogleAccessToken] = React.useState(null); const [userInfo, setUserInfo] = React.useState(null); const [request, response, promptAsync] = Google.useAuthRequest({ expoClientId: "###", iosClientId: "###", androidClientId: "###", webClientId: "###", }); React.useEffect(() => { if (response?.type === "success") { const { authentication } = response; setGoogleAccessToken(authentication.accessToken); } }, [response]); // 新增监听,accessToken更新时调用请求 React.useEffect(() => { if (googleAccessToken) { fetchUserInfo(); } }, [googleAccessToken]); const fetchUserInfo = () => { fetch("https://www.googleapis.com/oauth2/v3/userinfo", { headers: { Authorization: `Bearer ${googleAccessToken}` }, }) .then((response) => response.json()) .then((userInfoObj) => { setUserInfo(userInfoObj); console.log(userInfoObj); }) .catch((err) => { console.log(err); }); }; return ( <View> <Button disabled={!request} title="Login Here" onPress={() => { promptAsync(); }} /> {userInfo ? <Text>{userInfo.email}</Text> : <Text>Nope</Text>} </View> ); }
二、EventEmitter.removeListener废弃警告的问题
问题原因
旧版本的expo-web-browser库使用了React Native已废弃的removeListener API,触发警告。
解决方法
升级expo-web-browser到与当前Expo SDK匹配的最新兼容版本:
npx expo install expo-web-browser
该命令会自动安装适配当前项目的稳定版本,修复废弃API的调用问题。
若升级后警告仍存在,建议将Expo SDK整体升级到最新稳定版(操作前请备份项目):
npx expo upgrade
内容的提问来源于stack exchange,提问作者Kasun Jalitha
相关产品推荐
相关产品推荐

