On the way to success
On the way to success

Reputation: 210

An issue with react native expo auth-session implementation for google and firebase

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

Answers (1)

Andre Pena
Andre Pena

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

Related Questions