Google OAuth With Firebase In React Native

Google OAuth With Firebase In React Native

Authentication is a process where a user has to prove their identity in an application to gain access to a particular resource. There are many authentication strategies. However, the most notable ones provide one-click signups and logins for web and native mobile apps.

OAuth stands out as one-time click authentication without the need to provide passwords. OAuth is an open-source convention for using tokens for authentication and authorization. You can implement many OAuth providers in your apps, including Google, Facebook, Twitter, and GitHub.

These providers are well-packaged with cloud-hosted platforms such as Firebase. Firebase SDK supports Google sign-in, making it extremely easy to implement one-click authentications.

In this article, we will build a React Native application that will have Google OAuth using Firebase.

To follow along with this tutorial, it is important to have the following:

Setting up the application

Let’s dive and create a React Native application using Command Line Interface. React Native provides a built-in CLI to create an application. In this guide, we will use NPX to scaffold the project.

From your preferred directory, run the following command to initialize the React Native project:

npx react-native init react_native_googleauth

Note: while using this command and still you have a specific version of the CLI globally on your computer, you may run into unexpected issues. To avoid that, ensure you have the global CLI installed. You can run the following command to do so:

npm uninstall -g react-native-cli @react-native-community/cli

We need some packages to be able to communicate between Firebase and React Native. These include:

We will use the above packages to access Firebase and execute Google OAuth on a React Native front end. To install them navigate to the newly created project directory:

cd react_native_googleauth

Then run:

npm i @react-native-firebase/app @react-native-firebase/auth @react-native-google-signin/google-signin

Setting up Firebase

To implement this application, we need a working Firebase project. We just have a few steps. Let’s dive in and set up Firebase.

  • Proceed to your Firebase console from here

  • Click on the new project card.

  • Enter the application name, i.e., react_native_auth_app

  • Check the confirmation check box, then click on Continue.

Feel free to toggle between enabling or disabling google analytics in the project.

  • The project will be created in the next step. Once it is done, click on continue.

  • Once done, you will be directed to the dashboard page:

1 dashboard

  • Click on the Android icon to set up the application.

For Android package name, check your android/app/src/main/AndroidManifest.xml file in your React Native project and enter the package name as such:

2 android_package_name

Feel free to enter any application nickname.

  • Generate a signing certificate by running the following command from the terminal on your React Native project folder:
cd android && ./gradlew signingReport
  • On the generated certificates, Copy the SHA-1 that has: Task labeled as :app:signingReport, Variant as debugAndroidTest, and Config as debug.

  • Paste it in the certificate field, then click Register app.

  • Download the google-services.json file and place it under the android/app directory of React Native project.

  • From there, click on Next and then continue to the console.

  • From the application dashboard, click on authentication:

3 app_dashboard

  • On the resulting page, click on Get Started.

  • In the Sign in method tab, select Google as an additional provider:

4 additional_providers

  • On the resulting page, click on enable:

5 enable_google_auth

  • Select a project support email. Then click Save.

Configuring Firebase with React Native

Once Firebase is set, first, add the google-services plugin as a dependency in android/build.gradle as follows:

buildscript {
    dependencies {
        // ... the other dependencies
        classpath' com.google.gms:google-services:4.3.3'
    }
}

Then add the following properties on your android/app/build.gradle file to execute the ‘google-services’ plugin:

apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services'

Finally, define the authentication module as a dependency:

dependencies {
    // add the following
    implementation platform('com.google.firebase:firebase-bom:26.3.0')
    implementation' com.google.firebase:firebase-auth'
}

Setting up the app screens

We have Firebase ready and configured with React Native. Let’s create screens to handle Google Oauth.

In the project root folder, create a screens directory. Here we will create two screens:

  • For handling authentication. In the screens directory, create an Authenticate.js' file: we will log in a user here. Go ahead and create a button using GoogleSigninButton` as follows:
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { GoogleSigninButton } from '@react-native-google-signin/google-signin';

export default function Authenticate(props) {
    return (
        <View style={styles.screen}>
            <Text style={styles.title}>Google OAuth</Text>
            <GoogleSigninButton onPress={props.handleGoogleButtonPress} />
        </View>
    )
}
const styles = StyleSheet.create({
    screen: {
        display: 'flex',
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    },
    title: {
        fontSize: 25,
        marginBottom: 30
    }
})
  • Handling authenticated user screen. Once a user is signed in, we will show details of the authenticated user and log out. In the screens directory, create an Authenticated.js and add the following component to display user details.
import React from "react";
import { StyleSheet, Text, View, Image, Button } from 'react-native';
import auth from '@react-native-firebase/auth';

export default function Authenticated() {
    const user = auth().currentUser;
    return (
        <View style={styles.screen}>
            <Text style={styles.title}>You have logged in successfully</Text>
            <Image source={{ uri: user?.photoURL }} style={styles.image} />
            <Text style={styles.text}>{user?.displayName}</Text>
            <Text style={styles.text}>{user?.email}</Text>
            <View style={{ marginTop: 30 }}>
                <Button title= "Log out"/>
            </View>
        </View>
    )
}

const styles = StyleSheet.create({
    screen: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "#ffc2c2",
    },
    title: {
        fontSize: 25,
        marginBottom: 30,
    },
    image: {
        height: 150,
        width: 150,
        borderRadius: 150,
        marginBottom: 20,
    },
    text: {
        fontSize: 20,
    },
});

Open Source Session Replay

OpenReplayis an open-source, session replay suite that lets you see what users do on your web app, helping you troubleshoot issues faster. OpenReplay is self-hosted for full control over your data.

OpenReplay

Start enjoying your debugging experience -start using OpenReplay for free.

Handling Google Sign-in Authentication

To handle user sign-in, navigate to App.js and import the necessary modules.

import React,{useState} from 'react';
import auth from '@react-native-firebase/auth';
import { GoogleSignin } from '@react-native-google-signin/google-signin'
import Authenticate from './screens/Authenticate';
import Authenticated from './screens/Authenticated';

Configure GoogleSignin with your webClientId:

GoogleSignin.configure({
    webClientId: "your_webclient_id"
});

To get your WebClient id, click on Authentication from your Firebase app dashboard from the left pane. Click on the Sign-in method. Click on Google. Under Web SDK configuration, the Web client ID is a form field with a value in it. Copy the value and paste it in the above GoogleSignIn configuration as your your_webclient_id.

Define a state for checking whether the user is authenticated or not:

const App = () => {
    const [authenticated,setAuthenticated] = useState(false);
}

Define a listener for checking whether the user is logged in or not:

auth().onAuthStateChanged((user) => {
    if (user) {
        setAuthenticated(true);
    } else {
        setAuthenticated(false);
    }
});

Define a function for handling sign-in:

async function handleGoogleButtonPress() {
    try {
        // get the user id token
        const { idToken } = await GoogleSignin.signIn();
        // create a credential using the token
        const googleCredential = auth.GoogleAuthProvider.credential(idToken);
        // authenticate the user using the credential
        return auth().signInWithCredential(googleCredential);
    } catch (error) {
        console.log("error", error);
    }
}

Render the appropriate screen if the user is authenticated or not:

if (authenticated) {
    return <Authenticated />
}
return <Authenticate handleGoogleButtonPress={handleGoogleButtonPress} />

Handling Google Sign-out Authentication

To handle user Sign-out, navigate to the screens/Authenticated.js file and add auth().signOut() handler to your component. Here, ensure you import Firebase auth package:

import auth from '@react-native-firebase/auth';

Then update the Authenticated component as follows:

export default function Authenticated() {
    const user = auth().currentUser;
    return (
        <View style={styles.screen}>
            <Text style={styles.title}>You have logged in successfully</Text>
            <Image source={{ uri: user?.photoURL }} style={styles.image} />
            <Text style={styles.text}>{user?.displayName}</Text>
            <Text style={styles.text}>{user?.email}</Text>
            <View style={{ marginTop: 30 }}>
                <Button title="Log out" onPress={() => {
                    auth().signOut();
                }} />
            </View>
        </View>
    )
}

Combining the sign-in and sign out

At this point, your application should be ready. Go ahead and ensure your App.js file reflects as such:

import React, { useState } from 'react';
import auth from '@react-native-firebase/auth';
import { GoogleSignin } from '@react-native-google-signin/google-signin'
import Authenticate from './screens/Authenticate';
import Authenticated from './screens/Authenticated';

GoogleSignin.configure({
    webClientId: "your_webclient_id"
});

const App = () => {
    const [authenticated, setAuthenticated] = useState(false);

    auth().onAuthStateChanged((user) => {
        if (user) {
            setAuthenticated(true);
        } else {
            setAuthenticated(false);
        }
    });


    async function handleGoogleButtonPress() {
        try {
            // get the user id token
            const { idToken } = await GoogleSignin.signIn();
            // create a credential using the token
            const googleCredential = auth.GoogleAuthProvider.credential(idToken);
            // authenticate the user using the credential
            return auth().signInWithCredential(googleCredential);
        } catch (error) {
            console.log("error", error);
        }
    }

    if (authenticated) {
        return <Authenticated />
    }
    return <Authenticate handleGoogleButtonPress={handleGoogleButtonPress} />
};

export default App;

Testing the app

The application is now ready. Start the development server using the following command:

# using Metro Bundler
npx react-native start
# Start the app on an Android emulator
npm run android

Note: Run the application base on the React Native setup configured on your computer. For additional configurations, such as Target OS, check this guide for iOS setup.

Once the application is up and running, you will be served with the Sign-in screen as follows:

6 login_screen

Once the user is authenticated, the Authenticated screen will display the user details and button to handle Sign out as follows:

7 authenticated_screen

Conclusion

This guide helped you handle user authentication using Google OAuth provider. For any code references, check the application on this GitHub repository.

I hope you found this helpful. Happy coding!

A TIP FROM THE EDITOR: For another case study on authentication, don’t miss our Authentication In React 18 Using Firebase V9 article.

newsletter