React Native

React Native – Integrating Google Sign In

In this tutorial we are going to see how we can integrate Google SignIn in a React Native Application. We are going to implement this using Firebase Console. I am going to cover all the points which is necessary in the integration. Because I personally face many problems regarding this implementation. So let’s start the tutorial.

First of all you have to create a project using this command.

npx react-native init ProjectName

After running the project we are going to integrate the google sign in functionality.

So lets first open the Firebase Console clicking this link and register our app.

Step 1: Add a Project and Just Enter the details and Follow the steps.

Step 2: After that click on the android icon as below image.

Step 3: After that you got a screen like this where you enter your details.

For Android Package Name just go to this location and copy the package name.

Yourproject -> android -> app -> src -> main -> AndroidManifest.xml file.

After that just provide a name of the App as per your choice. And then for getting the SHA 1 you have to follow some steps like below:

  1. Open the command prompt and enter this command cd C:\Program Files\Java\jdk1.8.0_251\bin and navigate to this folder.
  2. After that enter keytool -list -v -keystore C:/Users/hp/ProjectName/android/app/debug.keystore -alias androiddebugkey -storepass android -keypass android and you will get SHA1 configuration like below image.

3. Copy the SHA1 and paste in the DebugSigning Certificate and when you Register your app you will get an error like below image.

4. For this we have to change the package name of our application and below are the steps for changing the package name.


I’ve changed project’ subfolder name from: “android/app/src/main/java/MY/APP/com/” to: “android/app/src/main/java/MY/APP/AnyName/

Then manually switched the old and new package ids:

In: android/app/src/main/java/MY/APP/NEW_ID/MainActivity.java:

package MY.APP.NEW_ID;

In android/app/src/main/java/MY/APP/NEW_ID/MainApplication.java:

package MY.APP.NEW_ID;

In android/app/src/main/AndroidManifest.xml:

package="MY.APP.NEW_ID"

And in android/app/build.gradle:

applicationId "MY.APP.NEW_ID"

(Optional) In android/app/BUCK:

android_build_config(
  package="MY.APP.NEW_ID"
)
android_resource(
  package="MY.APP.NEW_ID"
)

Gradle’ cleaning in the end (in /android folder):

./gradlew clean

Step 4: After that copy your new package name and paste in the Package Name of Firebase Console.

Step 5: Just Follow the other steps and download the google-service.json and paste that file in the ProjectName\android\app.

Step 6: After doing all these steps we are going to implement the library for Google SignIn.

npm install react-native-google-signin

//after that link this library

react-native link react-native-google-signin

Step 7: Just Update android/build.gradle with below codes where — Add this is written.

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        buildToolsVersion = "28.0.3"
        minSdkVersion = 16
        compileSdkVersion = 28
        targetSdkVersion = 28
        googlePlayServicesAuthVersion = "16.0.1"   --- Add this
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:3.5.2")
        classpath 'com.google.gms:google-services:4.1.0' --- Add this
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }

        google()  --- Add this
        jcenter()
        maven { url 'https://www.jitpack.io' }
    }
}

Step 8: Update android/app/build.gradle  with below codes where — Add this is written.

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    //noinspection GradleDynamicVersion
    implementation "com.facebook.react:react-native:+"  // From node_modules
    implementation(project(":react-native-google-signin"))   --- Add this
    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"

    debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
      exclude group:'com.facebook.fbjni'
    }

    debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.facebook.flipper'
    }

    debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.facebook.flipper'
    }

    if (enableHermes) {
        def hermesPath = "../../node_modules/hermes-engine/android/";
        debugImplementation files(hermesPath + "hermes-debug.aar")
        releaseImplementation files(hermesPath + "hermes-release.aar")
    } else {
        implementation jscFlavor
    }
}

task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
apply plugin: 'com.google.gms.google-services'   --- Add this

After that Run your App and check is there any error. If not, then we are going to implement the logic for google SignIn. You can get your web client id in your google-service.json file. And then paste that web client id in your app.js code.

App.js Code

import React from 'react';
import {
  StyleSheet,
  Text,
  View,
  Alert,
  Image,
  ActivityIndicator,
  TouchableOpacity,
} from 'react-native';
import {
  GoogleSignin,
  GoogleSigninButton,
  statusCodes,
} from 'react-native-google-signin';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userInfo: null,
      gettingLoginStatus: true,
    };
  }

  componentDidMount() {
    //initial configuration
    GoogleSignin.configure({
      //It is mandatory to call this method before attempting to call signIn()
      scopes: ['https://www.googleapis.com/auth/drive.readonly'],
      // Repleace with your webClientId generated from Firebase console
      webClientId: 'REPLACE_YOUR_WEB_CLIENT_ID_HERE',
    });
    //Check if user is already signed in
    this._isSignedIn();
  }

  _isSignedIn = async () => {
    const isSignedIn = await GoogleSignin.isSignedIn();
    if (isSignedIn) {
      alert('User is already signed in');
      //Get the User details as user is already signed in
      this._getCurrentUserInfo();
    } else {
      //alert("Please Login");
      console.log('Please Login');
    }
    this.setState({ gettingLoginStatus: false });
  };

  _getCurrentUserInfo = async () => {
    try {
      const userInfo = await GoogleSignin.signInSilently();
      console.log('User Info --> ', userInfo);
      this.setState({ userInfo: userInfo });
    } catch (error) {
      if (error.code === statusCodes.SIGN_IN_REQUIRED) {
        alert('User has not signed in yet');
        console.log('User has not signed in yet');
      } else {
        alert("Something went wrong. Unable to get user's info");
        console.log("Something went wrong. Unable to get user's info");
      }
    }
  };

  _signIn = async () => {
    //Prompts a modal to let the user sign in into your application.
    try {
      await GoogleSignin.hasPlayServices({
        //Check if device has Google Play Services installed.
        //Always resolves to true on iOS.
        showPlayServicesUpdateDialog: true,
      });
      const userInfo = await GoogleSignin.signIn();
      console.log('User Info --> ', userInfo);
      this.setState({ userInfo: userInfo });
    } catch (error) {
      console.log('Message', error.message);
      if (error.code === statusCodes.SIGN_IN_CANCELLED) {
        console.log('User Cancelled the Login Flow');
      } else if (error.code === statusCodes.IN_PROGRESS) {
        console.log('Signing In');
      } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
        console.log('Play Services Not Available or Outdated');
      } else {
        console.log('Some Other Error Happened');
      }
    }
  };

  _signOut = async () => {
    //Remove user session from the device.
    try {
      await GoogleSignin.revokeAccess();
      await GoogleSignin.signOut();
      this.setState({ userInfo: null }); // Remove the user from your app's state as well
    } catch (error) {
      console.error(error);
    }
  };

  render() {
    //returning Loader untill we check for the already signed in user
    if (this.state.gettingLoginStatus) {
      return (
        <View style={styles.container}>
          <ActivityIndicator size="large" color="#0000ff" />
        </View>
      );
    } else {
      if (this.state.userInfo != null) {
        //Showing the User detail
        return (
          <View style={styles.container}>
            <Image
              source={{ uri: this.state.userInfo.user.photo }}
              style={styles.imageStyle}
            />
            <Text style={styles.text}>
              Name: {this.state.userInfo.user.name}{' '}
            </Text>
            <Text style={styles.text}>
              Email: {this.state.userInfo.user.email}
            </Text>
            <TouchableOpacity style={styles.button} onPress={this._signOut}>
              <Text>Logout</Text>
            </TouchableOpacity>
          </View>
        );
      } else {
        //For login showing the Signin button
        return (
          <View style={styles.container}>
            <GoogleSigninButton
              style={{ width: 312, height: 48 }}
              size={GoogleSigninButton.Size.Wide}
              color={GoogleSigninButton.Color.Light}
              onPress={this._signIn}
            />
          </View>
        );
      }
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  imageStyle: {
    width: 200,
    height: 300,
    resizeMode: 'contain',
  },
  button: {
    alignItems: 'center',
    backgroundColor: '#DDDDDD',
    padding: 10,
    width: 300,
    marginTop: 30,
  },
});

Shaiv Roy

Hy Myself shaiv roy, I am a passionate blogger and love to share ideas among people, I am having good experience with laravel, vue js, react, flutter and doing website and app development work from last 7 years.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button