google 和 firebase 的 React Native expo auth-session 实现的问题

发布于 2025-01-17 17:27:17 字数 4060 浏览 0 评论 0原文

非常感谢您检查这个。

所以,这个错误在过去几天里成功地激怒了我。错误在于,每当 expo-auth-session => 这个钩子时,调用 const [request、response、promptAsync] = Google.useIdTokenAuthRequest 时,它会给出这个模糊且不太有用的 错误:[错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。发生这种情况的原因之一可能是:

为了向您提供有关此问题的更多详细信息,我们有一个 AuthProvider:

import React, {
  createContext,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import * as Google from "expo-auth-session/providers/google";
import * as WebBrowser from "expo-web-browser";
import {
  GoogleAuthProvider,
  onAuthStateChanged,
  signInWithCredential,
  signOut,
} from "@firebase/auth";

import { auth } from "../firebase";

const AuthContext = createContext({});


export default function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  // const [message, setMessage] = useState();
  // const [acessToken, setAccessToken] = useState();
  // const [request, response, promptAsync] = Google.useAuthRpnaapequest(config);

  async function signInWithGoogle() {
    console.log("@signInWithGoogle");

    WebBrowser.maybeCompleteAuthSession();
    console.log("In google accessing");

    // console.log(config);

    try {
      console.log("At try block");

      const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
        androidClientId:
          "95092903-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      });

      console.log("request: ", JSON.stringify(request));
      console.log("response: ", JSON.stringify(response));
    } catch (error) {
      console.log("error: ", error);
    }
  }

  return (
    <AuthContext.Provider
      value={{
        user,
        signInWithGoogle,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  return useContext(AuthContext);
}

它用于将所有内容包裹在其周围,如下所示:

import React from "react";
import Navigation from "./navigation";
import AuthProvider from "./hooks/useAuth";

export default function App() {
  console.log("We are in the app now");

  return (
    <AuthProvider>
      <Navigation />
    </AuthProvider>
  );
}

然后在登录屏幕中调用 signInWithGoogle(),如下所示:

import { View, Text, Button, TouchableOpacity } from "react-native";
import React from "react";
import { useAuth } from "../hooks/useAuth";

const LoginScreen = ({ navigation }) => {
  const { user, signInWithGoogle } = useAuth();

  console.log(user);
  return (
    <View
      style={{
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        width: "100%",
      }}
    >
      <TouchableOpacity
        style={{ marginTop: 40, width: "70%", height: "10%" }}
        onPress={signInWithGoogle}
      >
        <View
          style={{
            width: "100%",
            height: "80%",
            justifyContent: "center",
            alignItems: "center",
            backgroundColor: "#0bcc82",
          }}
        >
          <Text style={{ fontSize: 22 }}>Get In</Text>
        </View>
      </TouchableOpacity>
    
    </View>
  );
};

export default LoginScreen;

这就是控制台日志对于这段代码的信息:

@signInWithGoogle
In google accessing
At try block
error:  [Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
   

是的,类似问题的每一个部分和每一个细节都被吞噬了。他们中没有人给出哪怕一点点的暗示。我已经做了一切可能的事情来解决这个问题。我最后的避难所就是这里!

您能为这位新手编码员提供一些见解吗?或者你知道有什么办法摆脱这个吗?

Thanks a ton for checking this out.

So, there's this error that has been successful in irritating me for the last few days. The error is that whenever this hook of expo-auth-session => const [request, response, promptAsync] = Google.useIdTokenAuthRequest is called, it gives out this vague and not-so-useful error: [Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

To give you more details about this,we have an AuthProvider:

import React, {
  createContext,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import * as Google from "expo-auth-session/providers/google";
import * as WebBrowser from "expo-web-browser";
import {
  GoogleAuthProvider,
  onAuthStateChanged,
  signInWithCredential,
  signOut,
} from "@firebase/auth";

import { auth } from "../firebase";

const AuthContext = createContext({});


export default function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  // const [message, setMessage] = useState();
  // const [acessToken, setAccessToken] = useState();
  // const [request, response, promptAsync] = Google.useAuthRpnaapequest(config);

  async function signInWithGoogle() {
    console.log("@signInWithGoogle");

    WebBrowser.maybeCompleteAuthSession();
    console.log("In google accessing");

    // console.log(config);

    try {
      console.log("At try block");

      const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
        androidClientId:
          "95092903-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      });

      console.log("request: ", JSON.stringify(request));
      console.log("response: ", JSON.stringify(response));
    } catch (error) {
      console.log("error: ", error);
    }
  }

  return (
    <AuthContext.Provider
      value={{
        user,
        signInWithGoogle,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  return useContext(AuthContext);
}

And it's used to wrap everything around it, like this:

import React from "react";
import Navigation from "./navigation";
import AuthProvider from "./hooks/useAuth";

export default function App() {
  console.log("We are in the app now");

  return (
    <AuthProvider>
      <Navigation />
    </AuthProvider>
  );
}

And then the signInWithGoogle() is called in the login screen like this:

import { View, Text, Button, TouchableOpacity } from "react-native";
import React from "react";
import { useAuth } from "../hooks/useAuth";

const LoginScreen = ({ navigation }) => {
  const { user, signInWithGoogle } = useAuth();

  console.log(user);
  return (
    <View
      style={{
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        width: "100%",
      }}
    >
      <TouchableOpacity
        style={{ marginTop: 40, width: "70%", height: "10%" }}
        onPress={signInWithGoogle}
      >
        <View
          style={{
            width: "100%",
            height: "80%",
            justifyContent: "center",
            alignItems: "center",
            backgroundColor: "#0bcc82",
          }}
        >
          <Text style={{ fontSize: 22 }}>Get In</Text>
        </View>
      </TouchableOpacity>
    
    </View>
  );
};

export default LoginScreen;

And this is what the console logs have to say for us for this code:

@signInWithGoogle
In google accessing
At try block
error:  [Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
   

Yes, every part and particles of similar questions were devoured. Not one of them gave at least a tiny hint. Everything that's possible from my part to cut through this has been done. The final resort for me is here!

Can you offer some insights to this newbie coder? Or do you know any way out of this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

内心荒芜 2025-01-24 17:27:17

google.useidtokenauthrequest是一个react钩子,因此不能有条件地调用,并且在组件的渲染过程中应始终调用。查看钩子的规则: https://reactjs.s.s.org/docs/hooks-rules.htmlles.html

将其移至顶部,这样:

export default function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
        androidClientId:
          "95092903-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      });
   // ...
}

函数google.useidtokenauthrequest并没有真正执行任何操作,它只是准备以后执行。您现在可能会遇到其他错误,因为您正在尝试做的非常复杂,但这是对无效挂钩通话问题的答案。

Google.useIdTokenAuthRequest is a React hook, so it cannot be called conditionally and it should always be called during the render of a component. Check out the rules of hooks: https://reactjs.org/docs/hooks-rules.html.

Move it to the top, like this:

export default function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
        androidClientId:
          "95092903-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      });
   // ...
}

The function Google.useIdTokenAuthRequest is not really executing anything, it's just preparing to be executed later. You will probably have other errors now because this you are trying to do is very complex, but this is the answer to the invalid hook call problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文