Expo Auth Session谷歌登录需点击两次按钮才打开登录弹窗如何修复
React Native 谷歌登录需点击两次唤起弹窗的修复方案
问题原因
这个异常的核心是谷歌授权请求初始化时机和调用时机不匹配:
你使用的基于promptAsync的谷歌登录逻辑(expo生态的谷歌登录实现),在组件挂载时会异步生成授权请求实例、拉取平台侧的登录配置,这个初始化过程不会阻塞页面渲染。
- 第一次点击登录按钮时,授权请求实例还未完成初始化,此时调用
promptAsync会静默失败,不会弹出登录窗口;但点击触发的组件重渲染会同步推进初始化流程,等待实例完成准备 - 第二次点击时,授权请求实例已经完全就绪,
promptAsync可以正常执行,因此能成功唤起「Sign In with Google」弹窗
另外你的现有代码还有个小缺陷:登录逻辑启动时没有设置loading状态为true,仅在流程结束的finally块里把状态设为false,会导致加载状态的表现不符合预期。
修复步骤
- 第一步:在自定义authentication hook中,补全谷歌登录hook的解构,拿到代表请求就绪状态的
request对象:
import * as Google from 'expo-auth-session/providers/google'; // 替换为你自己在谷歌云控制台申请的各端客户端ID const [request, response, promptAsync] = Google.useAuthRequest({ androidClientId: '你的安卓客户端ID', iosClientId: '你的iOS客户端ID', webClientId: '你的Web端客户端ID', });
- 第二步:修改
SignInWithGoogle方法,增加就绪判断,补全加载状态逻辑:
const SignInWithGoogle = () => { console.log("clicked"); // 请求未就绪时直接终止逻辑 if (!request) return; // 补上登录启动时的加载状态设置 setLoading(true); promptAsync() .then(async (response) => { if (response.type === "success") { const credential = GoogleAuthProvider.credential( null, response.authentication.accessToken ); await signInWithCredential(auth, credential); } }) .catch((error) => setError(error)) .finally(() => setLoading(false)); };
- 第三步:修改Login组件中的登录按钮,在请求未就绪时禁用按钮,避免无效点击:
<Pressable style={{ backgroundColor: myColors.primary, padding: 20 }} onPress={SignInWithGoogle} // 授权请求未完成初始化时禁用按钮 disabled={!request} > <Text>Login</Text> </Pressable>
修改完成后,首次进入页面按钮会在请求初始化阶段处于禁用状态,初始化完成后点击一次即可正常唤起谷歌登录弹窗。
如果你使用的是非expo生态的
@react-native-google-signin/google-signin原生库,出现相同问题的原因是GoogleSignin.configure()配置方法为异步执行,第一次点击时配置未完成导致调用失败,只需要把configure方法放在应用入口的初始化流程中,等待配置完成后再渲染登录页面即可解决。
内容的提问来源于stack exchange,提问作者Sikandar Ali Chishty
相关产品推荐
相关产品推荐

