You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Expo应用Google登录跳转至Google.com问题求助

问题:Expo EAS构建APK后Google登录跳转至www.google.com

我正在为Expo React Native应用集成Google登录,遵循Expo官方文档《Auth with Google》。在Expo Go中登录完全正常,但通过EAS服务构建APK后,点击登录会加载一段时间,然后直接跳转到www.google.com,无法完成登录流程。作为新手已经折腾了20多小时,还是解决不了,恳请帮忙。

登录页面代码

import { StyleSheet, View, LogBox, Pressable, Text } from "react-native";
import { useEffect, useState } from "react";
import Fonts from "../utils/Fonts";
import Colors from "../utils/Colors";
import { db } from "../utils/firebase";
import GoogleIcon from "../icons/GoogleIcon";
import * as WebBrowser from "expo-web-browser";
import { LivornLogoIcon } from "../icons/HeaderIcons";
import { ref, onValue } from "firebase/database";
import FormComponent from "../components/FormComponent";
import * as Google from "expo-auth-session/providers/google";
import { useAndroidRipple } from "../hooks/useAndroidRipple";
import AsyncStorage from "@react-native-async-storage/async-storage";
import PrimaryButtonComponent from "../components/PrimaryButtonComponent";

WebBrowser.maybeCompleteAuthSession();
LogBox.ignoreLogs(["The useProxy option is deprecated and will be removed in a future release"]);

export default function LoginScreen({ setUserLoginInfo }) {
  const [token, setToken] = useState("");
  const [inviteCode, setInviteCode] = useState();
  const [isAuthorized, setIsAuthorized] = useState(true);
  const [errorMessage, setErrorMessage] = useState("");

  const [request, response, promptAsync] = Google.useAuthRequest({
    // iosClientId: "",
    androidClientId: "你的Android客户端ID",
    expoClientId: "你的Expo客户端ID",
    webClientId: "你的Web客户端ID",
  });

  useEffect(() => {
    handleEffect();
  }, [response, token]);

  async function handleEffect() {
    const user = await getLocalUser();
    if (!user) {
      if (response?.type === "success") {
        setToken(response.authentication.accessToken);
        getUserInfo(response.authentication.accessToken);
      }
    } else {
      setUserLoginInfo(user);
    }
  }

  const getLocalUser = async () => {
    const data = await AsyncStorage.getItem("@user");
    if (!data) return null;
    return JSON.parse(data);
  };

  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));
      setUserLoginInfo(user);
    } catch (error) {
      console.error("获取用户信息失败:", error);
    }
  };


  return (
    <View style={styles.container}>
      <LivornLogoIcon scale={6} marginLeft={10} />
      {isAuthorized && (
        <View style={styles.buttonContainer}>
          <Pressable
            disabled={!request}
            style={styles.googleButton}
            onPress={() => promptAsync()}
            android_ripple={useAndroidRipple(170)}
          >
            <GoogleIcon scale={0.35} marginRight={12} />
            <Text style={Fonts.primaryText}>Continue with Google</Text>
          </Pressable>
        </View>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 100,
    alignItems: "center",
    justifyContent: "flex-start",
    backgroundColor: Colors.blackTheme.backgroundPrimary,
  },
  buttonContainer: {
    width: "80%",
    marginTop: 20,
    overflow: "hidden",
    borderRadius: 100,
  },
  googleButton: {
    height: 60,
    borderRadius: 100,
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    backgroundColor: Colors.blackTheme.buttonAndIconColor,
  },
  errorMessage: {
    color: "red",
    marginTop: 20,
    marginBottom: -40,
  },
});

app.json配置

{
  "expo": {
    "name": "Livorn",
    "slug": "Livorn",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/LivornAdaptiveIcon.png",
    "userInterfaceStyle": "light",
    "splash": {
      "image": "./assets/LivornSplashScreen.png",
      "resizeMode": "contain",
      "backgroundColor": "#000000"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/LivornAdaptiveIcon.png",
        "backgroundColor": "#000000"
      },
      "package": "company.cubes.Livorn"
    },
    "web": {
      "favicon": "./assets/LivornFavicon.png"
    },
    "scheme": "Livorn",
    "extra": {
      "eas": {
        "projectId": "b198162a-e569-4414-8d5f-86148568b764"
      }
    }
  }
}

解决要点

  • 核对Android客户端ID:EAS构建的独立APK需要使用对应包名(company.cubes.Livorn)的OAuth客户端ID,和Expo Go用的expoClientId不是同一个。去Google Cloud控制台确认你填的androidClientId是为这个包名创建的。
  • 配置重定向URI:在Google Cloud的OAuth客户端设置里,添加重定向URI Livorn://auth(对应你app.json里的scheme),否则Google无法回调回你的应用,只能跳转到网页。
  • 检查代码语法:你的代码里useAuthRequest的参数列表中,androidClientId后面缺失逗号,会导致语法错误,修复后再构建。
  • 添加APK签名指纹:EAS构建的APK有专属的签名证书,把该证书的SHA-1指纹添加到Google Cloud的OAuth客户端设置里。可以通过eas credentials命令查看,或者在EAS Dashboard的项目凭证里找到。
  • 完善错误日志:在getUserInfo的catch块里添加console.error,构建后通过adb logcat查看具体错误,方便定位问题。

内容的提问来源于stack exchange,提问作者Harshit sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 00:44:53