Reputation: 210
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?
Upvotes: 0
Views: 2155
Reputation: 59336
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.
Upvotes: 1