Search code examples
javascriptreact-nativefacebookauthenticationgoogle-signin

React Native Google / Facebook Login


I'm quit new in React native but I would like to set up Google login but what I did didn't seem to work. (That will be a long post haha )

For Google Login:

I tried several tutorials on YouTube (this one for example: https://www.youtube.com/watch?v=DN9dQ_6ezvA)

"Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project."

I tried a lot of thing but it's really hard for me. So if someone could give me some help? Thanks you in advance guys, I continue the research on my side

Here is my code:

WebBrowser.maybeCompleteAuthSession();

export default function GoogleFunc({largeur}) {
  const fontRegular = require("../../assets/Manrope-Regular.ttf");
  const fontBold = require("../../assets/Manrope-Bold.ttf");

  const [fontsLoaded] = useFonts({
    ManropeRegular: fontRegular,
    ManropeBold: fontBold,
  });

  const [accessToken, setAccessToken] = React.useState();
  const [userInfo, setUserInfo] = React.useState();
  const [request, response, prompAsync] = Google.useIdTokenAuthRequest({
    androidClientId:
      "ANDROID_CLIENT_ID",
    iosClientId:
      "CLIENT_CLIENT_ID",
    clientId:
      "CLIENT_ID",
  });

  React.useEffect(() => {
    if (response?.type === "success") {
      console.log("response: ", response.params);
      setAccessToken(response.params.id_token);
      accessToken && fetchUserInfo();
    }
  }, [response, accessToken]);

  async function fetchUserInfo() {
    console.log("test222");
    let response = await fetch("https://www.googleapis.com/userinfo/v2/me", {
      headers: {Authorization: `Bearer ${accessToken}`},
    });
    const useInfo = await response.json();
    console.log("useinfo: ", useInfo);
    setUserInfo(useInfo);
  }

  const ShowUserInfo = () => {
    if (userInfo) {
      console.log("userinfooofofof: ", userInfo);
      return (
        <View style={styles.userInfo}>
          <Image source={{uri: userInfo.picture}} style={styles.profilePic} />
          <Text>Welcome {userInfo.name}</Text>
          <Text>{userInfo.email}</Text>
        </View>
      );
    }
  };

  return (
    <View style={styles.container}>
      {userInfo && <ShowUserInfo />}
      {userInfo == null && (
        <>
          <TouchableOpacity
            style={[styles.googleBtn, {width: largeur}]}
            disabled={!request}
            onPress={() => {
              prompAsync();
            }}
          >
            <Image
              style={{
                height: height * 0.024,
                width: width * 0.057,
                left: width * 0.035,
                top: height * 0.013,
              }}
              source={require("../../assets/images/google-logo.png")}
            />
            <Text
              style={{
                textAlign: "center",
                fontFamily: "ManropeSemiBold",
                fontSize: 17,
                color: "#262626",
                bottom: height * 0.01,
              }}
            >
              Continuer avec Google
            </Text>
          </TouchableOpacity>
        </>
      )}
    </View>
  );
}

For Facebook:

I tried to set up the login with / without firebase but I already got the same issue : an error ... I'm trying to solve it since last week but I don't understand how can i fix these problems ...

Here's my code without Firebase:

import React, {useState} from "react";
import {
  StyleSheet,
  Text,
  View,
  Image,
  TouchableOpacity,
  ActivityIndicator,
} from "react-native";
import * as Facebook from "expo-facebook";

export default function FacebookFunc() {
  const [isLoggedin, setLoggedinStatus] = useState(false);
  const [userData, setUserData] = useState(null);
  const [isImageLoading, setImageLoadStatus] = useState(false);

  async function faceookLogIn() {
    try {
      await Facebook.initializeAsync({
        appId: "APP ID",
      });
      const {type, token, expirationDate, permissions, declinedPermissions} =
        await Facebook.logInWithReadPermissionsAsync({
          permissions: ["public_profile"],
        });
      if (type === "success") {
        // Get the user's name using Facebook's Graph API
        const response = await fetch(
          `https://graph.facebook.com/me?access_token=${token}`
        );
        Alert.alert("Logged in!", `Hi ${(await response.json()).name}!`);
      } else {
        // type === 'cancel'
      }
    } catch ({message}) {
      alert(`Facebook Login Error: ${message}`);
    }
  }

  logout = () => {
    setLoggedinStatus(false);
    setUserData(null);
    setImageLoadStatus(false);
  };

  return isLoggedin ? (
    userData ? (
      <View style={styles.container}>
        <Image
          style={{width: 200, height: 200, borderRadius: 50}}
          source={{uri: userData.picture.data.url}}
          onLoadEnd={() => setImageLoadStatus(true)}
          // GERER QUAND MARCHERA
        />
        <ActivityIndicator
          size={"large"}
          color={"#0000ff"}
          animating={!isImageLoading}
          style={{position: "absolute"}}
        />
        <Text style={{fontSize: 22, marginVertical: 10}}>
          Hi {userData.name}!
        </Text>
        <TouchableOpacity style={styles.logoutBtn} onPress={logout}>
          <Text style={{color: "#fff"}}>Logout</Text>
        </TouchableOpacity>
      </View>
    ) : null
  ) : (
    <View style={styles.container}>
      <TouchableOpacity style={styles.loginBtn} onPress={faceookLogIn}>
        <Text style={{color: "#fff", textAlign: "center"}}>
          Login with facebook
        </Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {},
  loginBtn: {
    backgroundColor: "#4267b2",
    paddingVertical: 10,
    borderRadius: 10,
    width: "95%",
  },
  logoutBtn: {
    backgroundColor: "grey",
    includeFontPadding: 10,
    paddingHorizontal: 20,
    borderRadius: 20,
    position: "absolute:",
    bottom: 0,
    marginBottom: 200,
  },
});

And here my code when I trying with Firebase:

The error:

Possible Unhandled Promise Rejection (id: 0):
TypeError: null is not an object (evaluating 'LoginManager.logInWithPermissions')

The code:

import React from "react";
import {LoginManager, AccessToken} from "react-native-fbsdk-next";
import {
  StyleSheet,
  View,
  Text,
  Image,
  TouchableOpacity,
  Button,
} from "react-native";
import {
  getAuth,
  signInWithCredential,
  FacebookAuthProvider,
} from "firebase/auth";
import "expo-dev-client";

import app from "./firebaseSetup";

export default function App() {
  const SignInWithFB = async () => {
    const result = await LoginManager.logInWithPermissions([
      "public_profile",
      "email",
    ]);
    if (result.isCancelled) {
      throw new Error("User cancelled login");
    }
    const data = await AccessToken.getCurrentAccessToken();
    if (!data) {
      throw new Error("Something went wrong obtaining access token");
    }
    const auth = getAuth(app);

    const credential = FacebookAuthProvider.credential(data.accessToken);
    const user = await signInWithCredential(auth, credential);
    console.log(user);
  };

  return (
    <View>
      <Button title="Sign in with facebook" onPress={SignInWithFB}></Button>
    </View>
  );
}

const styles = StyleSheet.create({});

I initialize my firebaseSetup like this:

import {initializeApp} from "firebase/app";

// Initialize Firebase
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: "",
};

const app = initializeApp(firebaseConfig);
export default app;

I continue my research by my side but if someone could help me with this problem (which is probably stupid), thanks you in advance...

PS: There is the error for Facebook without firebase:

Facebook Login Error: undefined is not an object (evaluating'_ExponentFacebook.default.InitializeAsync')


Solution

  • You have to use expo auth session to implement oAuth in Expo

    import React,{useState} from 'react';
    import { useNavigation } from "@react-navigation/native";
    import Fontisto from '@expo/vector-icons/Fontisto';
    import { TouchableOpacity,StyleSheet, Alert } from 'react-native';
    import * as WebBrowser from 'expo-web-browser';
    import * as Facebook from 'expo-auth-session/providers/facebook';
    import {makeRedirectUri, ResponseType } from 'expo-auth-session';
    import { useDispatch } from "react-redux";
    
    WebBrowser.maybeCompleteAuthSession();
    
    export default function FacebookAuth(){
    
      const [isLoading, setIsLoading] = useState(false);
      const navigation = useNavigation();
      const dispatch = useDispatch();
    
          const [request, response, promptAsync] = Facebook.useAuthRequest({
            responseType: ResponseType.Token,
            clientId: 'YOUR_CLIENT_ID',
            scopes: ['public_profile', 'email'],
            redirectUri: makeRedirectUri({ useProxy: true })
          },
          { useProxy: true });
        
          React.useEffect(() => {
            if (response?.type === 'success') {
              setIsLoading(true);
              const accessToken = response.authentication.accessToken;
    
            console.log(accessToken);
            }
          }, [response]);
    
    
        return(
          <>
            <TouchableOpacity disabled={!request} style={styles.socialLoginButton}
            onPress={() => {
                promptAsync();
              }}
            >
                 <Fontisto name='facebook' color={'white'} size={25}/>
            </TouchableOpacity>
          </>
        )
    }
    
    const styles = StyleSheet.create({
        socialLoginButton:{
            margin:3,
            backgroundColor:'blue',
            padding:10,
            borderRadius:50,
            width:50,
            height:50,
            justifyContent:'center',
            alignItems:'center',
            margin:10,
          }
    })
    
    

    Here's the code for it, you have to configure it according to your needs. here's the link for expo auth session. - here