google 和 firebase 的 React Native expo auth-session 实现的问题
非常感谢您检查这个。
所以,这个错误在过去几天里成功地激怒了我。错误在于,每当 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
google.useidtokenauthrequest
是一个react钩子,因此不能有条件地调用,并且在组件的渲染过程中应始终调用。查看钩子的规则: https://reactjs.s.s.org/docs/hooks-rules.htmlles.html 。将其移至顶部,这样:
函数
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:
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.