Skip to main content

Google Login in React Native with Firebase

· 16 min read
Full Stack Developer
Last updated on October 3, 2022

react native google login

Login with Google is a convenient way to allow users to register and authenticate into your React Native app. It reduces friction in the onboarding flow, and therefore it maximizes user growth. Firebase provides a seamless experience of adding Google Login into any React Native app with almost no effort. In this React Native tutorial, we are going to implement Login with Google in React Native with Firebase.

Not only a social provider can act as a single source of authentication between your users and your app, but it also eliminates the need to implement extra functionalities that can bring a lot of hassle. Some of these functionalities can be email verification, forgot password, reset password, one click email, and so on.

In this tutorial, by using a package provided by React Native community and by leveraging Firebase to access auth credentials, let us learn how you can add Google sign-in provider method in your React Native apps.

1. Installing dependencies

Start by creating a new React Native project. Do note that this tutorial uses a react-native version above 0.60.x. If you are using a version below that, make sure to seek guidance on how to link native binaries for the libraries mentioned in this tutorial.

Open up a terminal window, and generate a new React Native project as follows:

npx react-native init rnGoogleSignIn

# navigate inside the directory
cd rnGoogleSignIn

Now, install the package @react-native-community/google-signin:

yarn add @react-native-community/google-signin

Since I’ll use the iOS simulator to test the demo app in this tutorial, I am going to discuss the iOS configuration part in details.

A word of caution: Android developers please note that you are going to follow the guide from here on how to configure this library to React Native app.

2. Create a new Firebase Project

Right now, you are going to need a Firebase project for two reasons:

  • Creating a Google Project

  • Access to WEB_CLIENT_ID and REVERSE_CLIENT_ID of a Google Project

For that, go to Firebase console and create a new project.

create new project

Complete the details of your Firebase project.

complete details in project

Click the button Create project and you’ll be redirected to the dashboard screen. On the left side menu, click the settings icon, and then go to Project Settings.

create project button click

From there, click on the Add app button, select the appropriate platform, and follow the included instructions. Select the appropriate platform depending on the mobile OS. For example, for this tutorial, I am going to select iOS.

Add App

Then, enter the details regarding the bundle name. After that, in step 2 download the file GoogleService-info.plist if your selected platform in the previous step is iOS.

Enter details

For Android devs, you will download google-services.json and save it at the location android/app/.

Mega Bundle Sale is ON! Get ALL of our React Native codebases at 90% OFF discount 🔥

Get the Mega Bundle

3. Enable Google Sign in from Firebase

From the side menu, go to the Authentication tab and then select Sign-in methods. You are going to be welcomed by all the providers that a Firebase project supports for any type of platforms such as web or mobile.

Enable the Google Sign-in method.

Enabling google sign in

Make sure you save the web client id inside your React Native project in a file utils/keys.js:

export const WEB_CLIENT_ID = "YOU_WEB_CLIENT_ID";

4. Configure Google-Signin library

To begin, open the file ios/Podfile and add the following line. This is going to install the Google Signin SDK using Cocoapods.

pod 'GoogleSignIn', '~> 5.0.2'

Open a terminal window to install the pods:

cd ios/

pod install

# after pods install
cd..

Open the ios/rnGoogleSignIn.xcworkspace inside Xcode. Go to Build phases panel and under it open a section Link binary with libraries to make sure libRNGoogleSignin.a exists.

Ios firebase react

Also, under Copy Bundle Resources, make sure GoogleService-Info.plist exists. If not, manually add it.

checking google info

Then, open the Info panel and go to the section URL Types.

URL Types

Add REVERSE_CLIENT_ID (which can be found in file GoogleService-Info.plist) as the value of the field URL Schemes.

Adding REVERSE_CLIENT_ID

That’s it. You can now start working on the app.

5. Build a Login Screen Component

Create a new file screens/Login.js in your React Native project. Start by importing the following statements.

import React, { useState, useEffect } from "react";
import {
View,
Text,
StatusBar,
Image,
StyleSheet,
Button,
Alert,
} from "react-native";
import {
GoogleSigninButton,
GoogleSignin,
statusCodes,
} from "@react-native-community/google-signin";
import { WEB_CLIENT_ID } from "../utils/keys";

In the above snippet, WEB_CLIENT_ID is what you saved from Firebase Google Sign in the panel, earlier in this tutorial.

The google-signin library also provides some ready to use helper functions as well as a visual component to be rendered directly within the app. One is called GoogleSigninButton. This button component can be customized to your needs.

GoogleSignin contains the API functionalities that are going to be used to sign in, and sign out. The statusCodes import is essential in determining what type of error has occurred during the process of sign in.

Next, let us define three state variables using React.useState() hook to keep track of

  • userInfo for the user information after a successful login. Initially, it going to be null.

  • isLoggedIn to check whether the user is logged in or not. Initially, it going to be false.

  • error that is going to be for statusCodes. Initially, it going to be null.

{
idToken: string,
serverAuthCode: string,
scopes: Array<string>, // on iOS this array is empty if no additional scopes are defined
user: {
email: string,
id: string,
givenName: string,
familyName: string,
photo: string, // url
name: string // full name
}
}

After a successful sign-in, the process returns a user object (an example shown above) that is going to be stored inside the userInfo state variable.

User Info State

export default function Login() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [userInfo, setUserInfo] = useState(null);
const [error, setError] = useState(null);
}

Create a helper function called configureGoogleSign(). Inside this function, it is essential to configure GoogleSignin options such as webClientId and offlineAccess.

function configureGoogleSign() {
GoogleSignin.configure({
webClientId: WEB_CLIENT_ID,
offlineAccess: false,
});
}

It is also essential to call this helper method before the actual signin method is called. Thus, the method is required to be invoked when the app starts. This is going to be done with the help of React.useEffect().

useEffect(() => {
configureGoogleSign();
}, []);

Then, define a method called signIn that is going to be an asynchronous function. This method is responsible to prompt a modal to let the user sign in into your React Native application. On success, it also provides a valid userInfo object. On error, there can be different scenarios that are essential to handle using statusCodes as shown below.

async function signIn() {
try {
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();
setUserInfo(userInfo);
setError(null);
setIsLoggedIn(true);
} catch (error) {
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
// when user cancels sign in process,
Alert.alert("Process Cancelled");
} else if (error.code === statusCodes.IN_PROGRESS) {
// when in progress already
Alert.alert("Process in progress");
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
// when play services not available
Alert.alert("Play services are not available");
} else {
// some other error
Alert.alert("Something else went wrong... ", error.toString());
setError(error);
}
}
}

For example, when a status code from the above snippet renders due to an error, it is going to be displayed in an alert box like below:

status code alert

Next, create another asynchronously invoked helper method called getCurrentUserInfo(). This method is going to return the current user.

async function getCurrentUserInfo() {
try {
const userInfo = await GoogleSignin.signInSilently();
setUserInfo(userInfo);
} catch (error) {
if (error.code === statusCodes.SIGN_IN_REQUIRED) {
// when user hasn't signed in yet
Alert.alert("Please Sign in");
setIsLoggedIn(false);
} else {
Alert.alert("Something else went wrong... ", error.toString());
setIsLoggedIn(false);
}
}
}

Mega Bundle Sale is ON! Get ALL of our React Native codebases at 90% OFF discount 🔥

Get the Mega Bundle

The last asynchronous method your app needs is called signOut(). This is going to sign out the user from the app.

async function signOut() {
try {
await GoogleSignin.revokeAccess();
await GoogleSignin.signOut();
setIsLoggedIn(false);
} catch (error) {
Alert.alert("Something else went wrong... ", error.toString());
}
}

6. Add Google Sign In Button

To continue directly from the previous section, add the following return statement to the Login screen component. This is going to display a Sign In button.

export default function Login() {
// ...
return (
<>
<StatusBar barStyle="dark-content" />
<View style={styles.container}>
<GoogleSigninButton
style={styles.signInButton}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Dark}
onPress={() => signIn()}
/>
</View>
</>
);
}

The corresponding styles of the above snippet are defined as:

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
signInButton: {
width: 192,
height: 48,
},
});

Now, build the app using the correct OS platform from a terminal window:

npx react-native run-ios
# or
npx react-native run-android

This is going to provide you the following output:

Login with google

7. Check the user’s login state

In this section, let us display the Login screen to display a message whether a user is logged in or not after the Sign-in button gets pressed.

<View style={styles.statusContainer}>
{isLoggedIn === false ? (
<Text style={styles.message}>You must sign in!</Text>
) : (
<Button onPress={() => signOut()} title='Sign out' color='#332211' />
)}
</View>```

If the user is logged in, we are going to display a sign out button that you will see shortly. Here are the corresponding styles for above code snippet:

```javascript
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
signInButton: {
width: 192,
height: 48
}
statusContainer: {
marginVertical: 20
},
message: {
fontSize: 20,
color: 'red'
}
})

Here is the output after this step:

display output after login

8. Display the user information

The final piece of the puzzle is to display the user information when they successfully log in.

Here is the complete code snippet of what is being rendered on the Login screen. Using the userInfo object, the value of the user’s name or profile image is being obtained.

return (
<>
<StatusBar barStyle="dark-content" />
<View style={styles.container}>
<GoogleSigninButton
style={styles.signInButton}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Dark}
onPress={() => signIn()}
/>
<View style={styles.statusContainer}>
{isLoggedIn === false ? (
<Text style={styles.message}>You must sign in!</Text>
) : (
<Button onPress={() => signOut()} title="Sign out" color="#332211" />
)}
</View>
<View style={styles.userInfoContainer}>
{isLoggedIn === true ? (
<>
<Text style={styles.displayTitle}>
Welcome {userInfo.user.name}
</Text>
<View style={styles.profileImageContainer}>
<Image
style={styles.profileImage}
source={{
uri: userInfo && userInfo.user && userInfo.user.photo,
}}
/>
</View>
</>
) : null}
</View>
</View>
</>
);

Also, here are the complete styles:

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
signInButton: {
width: 192,
height: 48,
},
statusContainer: {
marginVertical: 20,
},
message: {
fontSize: 20,
color: "red",
},
userInfoContainer: {
marginVertical: 20,
},
profileImageContainer: {
marginTop: 32,
paddingHorizontal: 24,
flexDirection: "row",
justifyContent: "center",
},
profileImage: {
width: 100,
height: 100,
},
displayTitle: {
fontSize: 22,
color: "#010101",
},
});

Mega Bundle Sale is ON! Get ALL of our React Native codebases at 90% OFF discount 🔥

Get the Mega Bundle

Here is the final demo so far. When the app renders for the first time and the user clicks on the sign-in button.

final demo

A modal appears for the user to enter their Google account credentials.

modal with google account credientials

On successful sign in:

display after signin

If the app is closed or the user has already logged in for the first time, the helper method getCurrentUserInfo() is triggered to avoid the user to enter their credentials again and again. This method is called Silent Login and is provided by GoogleSignin.signInSilently().

app logout result

That’s it. You have just learned how to implement a Google Sign in a React Native app using Firebase. In the next section, let us extend our journey a bit.

9. Integrating Firebase SDK

Since you are already using Firebase, let’s store the instance of the user’s login information. In real-time mobile apps, this is a helpful feature since Firebase provides you a backend system without setting it up one. Usually, a mobile app is going to store user’s data or behavior in relation to the app on a custom backend or a provider like Firebase.

To begin connecting Firebase SDK with this React Native app, open up the terminal window and start by installing the latest version (the version 6 at the time of writing this tutorial) of react-native-firebase.

yarn add @react-native-firebase/app

If you have used react-native-firebase version 5 or below, you must have noticed that it was a monorepo that used to manage all Firebase dependencies from one module.

Version 6 brings you to only install those Firebase dependencies based on features that you want to use. For example, in the current app, you are going to start by adding the auth package. Also, do note that the core module: @react-native-firebase/app is always required.

10. Adding Firebase credentials to an iOS app

Since you have already gone through the process of creating a GoogleService-Info.plist file, let us complete the remaining steps.

Open ios/rnGoogleSignIn/AppDelegate.m file and add the following header.

#import <Firebase.h>

Within the didFinishLaunchingWithOptions method, add the following configure method:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([FIRApp defaultApp] == nil) {
[FIRApp configure];
}

Open a terminal window to install pods.

cd ios/ && pod install

# after pods are installed
cd ..

11. Installing Firebase auth package

To support Google Sign in from Firebase, open a terminal window to install the auth package.

yarn add @react-native-firebase/auth

# Using iOS
cd ios/ && pod install

# After installing
cd ..

12. Store user credentials in Firebase backend

The react-native-firebase package requires you to use @react-native-community/google-signin package since the latter provides access to a user’s accessToken and idToken. Both of these values are necessary to create a Firebase credential.

Start by importing the following statement inside the Login.js screen component.

// ... after other import statements
import { firebase } from "@react-native-firebase/auth";

All you have to do is modify the asynchronous signIn() helper method. Add the following code snippet in the try block to create a new firebase credential with tokens as well as save the credential to the firebase backend using auth().signInWithCredential().

// create a new firebase credential with the token
const { accessToken, idToken } = await GoogleSignin.signIn();
const credential = firebase.auth.GoogleAuthProvider.credential(
idToken,
accessToken
);

// login with credential
await firebase.auth().signInWithCredential(credential);

That’s it. Now, when a user logs in through the app, their credential is going to be saved as shown below.

credientials saved

Looking for a custom mobile application?

Our team of expert mobile developers can help you build a custom mobile app that meets your specific needs.

Get in Touch

Conclusion

Thanks for going through the whole tutorial. I am sure you must have learned the key points here. Let me summarize it again for you. In this tutorial, you learned:

  • How to integrate and use Google Sign-in provider

  • Access user’s details from their Google account

  • Use @react-native-community/google-signin package

  • Integrating react-native-firebase version package in a react native app

  • Store user credentials in Firebase backend

That’s how you add a Login with Google feature to any React Native app. Firebase is a great tool that developers can leverage in order to build serverless cross-platform mobile apps really quickly.

If you run into any issues while adding Google Login into your React Native apps, please let us know in the comments. Also, if you’ve enjoyed this tutorial, please consider following us on Twitter to get notified of more tutorials and starter kits.

Next Steps

Now that you have learned about resources to learn React Native development, here are some other topics you can look into

If you need a base to start your next React Native app, you can make your next awesome app using manyReact Native template.