How to Integrate Google Sign-in Authentication into a Crowdbotics Mobile App

John Bender
Crowdbotics
Published in
12 min readApr 17, 2020

We’ve recently made some updates to our Crowdbotics Apps Dashboard. We’ve also spoken with Crowdbotics users who have had success architecting Crowdbotics apps in fields like software development and consulting. In other words, we’re excited to share new ways for you to take advantage of Crowdbotics and learn more about mobile development.

In this post, we’re going to cover the following list of topics:

  • Creating a mobile app from scratch using Crowdbotics App Dashboard in a matter of minutes
  • Installing google-signin dependencies
  • Integrating a Firebase project
  • Using Google Sign-in auth provider from Firebase
  • Configuring Google Sign-in library
  • Using Crowdbotics login screen components
  • Verifying and authenticating the real-time user

Do note that the Google Sign-in strategy discussed in this tutorial works not only with Crowdbotics-generated React Native apps, but even with vanilla React Native apps.

Requirements

Make sure you meet the following requirements:

For a complete walkthrough on how to set up a development environment for React Native, you can go through official documentation here. To follow this tutorial as closely as possible, please make sure you are using a version of React Native above 0.60.x.

Creating a mobile app using Crowdbotics App Dashboard

It’s simple to create a new mobile app from scratch within your Crowdbotics account. Once you are logged in, you are going to be welcomed by the following dashboard screen.

To start the process of creating a new app, click on the + button from the sidebar menu.

In the next screen, you can create a new app. Select Build from Scratch, enter the name of your mobile app, and select the app type Mobile App. Lastly, click on the Create App button.

If you have not connected your GitHub account to your Crowdbotics account, then you can see a link to your code repository by selecting the “Commits” tab in the “App activity” section of the dashboard.

If you have previously connected your GitHub account to your Crowdbotics account, then you will receive an email invite within minutes to a private repository of the React Native app project generated by Crowdbotics.

If you have logged in through your GitHub account, you can directly clone the app by visiting the link sent via email.

On the dashboard, you will be notified when the process of generating a new app template is complete.

You should have cloned the repo to your local development environment in order to proceed. To build the React Native app, make sure to navigate inside the project directory through a terminal and run the following commands in series to install npm modules as well as any cocoapods for iOS development.

cd googlesignin-15731

yarn install

# after npm dependencies are installed
# make sure you have npx installed
npx pod-install

And that’s it! You have successfully built a new React Native app from scratch using the Crowdbotics App Dashboard template.

Installing Google Sign-in dependency

Navigate to the Libraries tab in your dashboard and locate the “Install library” search window. Search for react-native-google-signin and click "+ Install", then save to add it to your project.

If you prefer to install this package from the command line instead, you can also open up a terminal window and 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 detail.

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 a React Native app.

Create a new Firebase project

The Google Sign-in package provider requires you to have a Firebase project connected to the React Native app. The main things that you will need to integrate a Firebase project for are:

  • Creating a Google Project
  • Access to WEB_CLIENT_ID and REVERSE_CLIENT_ID of a Google Project

Start by opening the Firebase console and create a new project.

Enter the details of your Firebase project.

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

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.

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.

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

How to 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 platform, such as web or mobile.

Enable the Google Sign-in method as shown below.

Make sure you save the web client ID inside your React Native project in a file called src/utils/keys.js as shown below.

export const WEB_CLIENT_ID = 'YOUR_WEB_CLIENT_ID';

How to set up Google Sign-in library

To make sure the Google Sign-in library you installed earlier in this tutorial from the React Native community works on iOS devices, you have to add the pod manually and modify the file ios/Podfile as shown below.

pod 'GoogleSignIn', '~> 5.0.2'

Open up a terminal window and install pods by executing the following command.

npx pod-install

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

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

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

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

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

Build a login screen

Let’s complete our app and build the Login screen component that is going to handle all the communication with the Google Sign-in package that you previously installed. To test it out, you are going to need a real-time Google account ID.

To get started, create a Login/index.js file inside the src/features/ directory of your Crowdbotics project. Start by importing all the necessary statements that are required to build this component as shown below. Make sure to create a login class component as well and export it.

import React, { Component } from 'react';
import {
Image,
View,
Dimensions,
StyleSheet,
StatusBar,
Alert
} from 'react-native';
import { Layout, Text, Button } from 'react-native-ui-kitten';
import { scaleModerate } from '../../utils/scale';
import {
GoogleSigninButton,
GoogleSignin,
statusCodes
} from '@react-native-community/google-signin';
import { WEB_CLIENT_ID } from '../../utils/keys.js';

class LoginScreen extends Component {}

export default LoginScreen;

The import statements in the above snippet are easy to follow. Apart from some core API components from react-native, Crowdbotics templates by default use the react-native-ui-kitten UI library, so you can use its pre-defined components. UI kitten is one of the most complete UI libraries to quickly build React Native apps. So far we are only going to use three UI components from it.

Next is a custom component to scale the image in the background. For your reference, you can find this file at ../../utils/scale.js with the following code snippet in your project repository.

import { Dimensions } from 'react-native';

const { width, height } = Dimensions.get('window');

// Guideline sizes are based on standard ~5" screen mobile device
const guidelineBaseWidth = 350;
const guidelineBaseHeight = 680;

const scale = size => (width / guidelineBaseWidth) * size;
const scaleVertical = size => (height / guidelineBaseHeight) * size;
const scaleModerate = (size, factor = 0.5) =>
size + (scale(size) - size) * factor;

export { scale, scaleVertical, scaleModerate };

Lastly, there are three helper components that the current app requires in order for the Google Sign-in integration to work with the current Crowdbotics React Native app. Here is a brief description of each of the helper methods imported from @react-native-community/google-signin.

  • GoogleSignin gives access to the Public API for the module. This object contains many helper methods such as signIn, signOut, and, more importantly, configure to check whether the client ID being used is correct or not.
  • GoogleSigninButton gives a functional UI login button such that you don't have to create one from scratch.
  • statusCodes are useful when determining which kind of error has occurred during the sign-in process. They have to be imported along with GoogleSignIn.

Now that you’ve learned about their purpose, let’s get back to the app.

Create a state object with three properties to keep track of inside the class component Login.

  • userInfo for the user information after a successful login. Initially, it's going to be null.
  • isLoggedIn to check whether the user is logged in or not. Initially, it's going to be false.
  • error that is going to be for statusCodes. Initially, it's going to be null.
state = {
isLoggedIn: false,
userInfo: null,
error: null
};

Next, it is mandatory to call the GoogleSignin.configure() method before attempting to call signIn(). That said, this method has to be called whenever the app renders for the first time, so it is better to call this method in a lifecycle method as shown below.

componentDidMount() {
this.configureGoogleSign();
}


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

Then, define a method called signIn that is going to be an asynchronous function. This method is responsible for prompting a modal to let the user sign in to 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.

signIn = async () => {
try {
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();
this.setState({ userInfo });
this.setState({ error: null });
this.setState({ isLoggedIn: 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());
this.setState({ 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:

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

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

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

signOut = async () => {
try {
await GoogleSignin.revokeAccess();
await GoogleSignin.signOut();
this.setState({ isLoggedIn: false });
} catch (error) {
Alert.alert('Something else went wrong... ', error.toString());
}
};

To display an image background on the home screen, let us create another helper method called renderImage() with the following code snippet.

renderImage = () => {
const screenSize = Dimensions.get('window');
const imageSize = {
width: screenSize.width,
height: screenSize.height - scaleModerate(500, 1)
};

return (
<Image
style={[imageSize]}
source={require('../../assets/images/backgroundLoginV1.png')}
/>
);
};

Now, let us render the background image first with the Google Sign-in button component from the community module.

render() {
return (
<Layout style={{ flex: 1, paddingVertical: 15 }}>
<StatusBar barStyle='light-content' />
{this.renderImage()}
<View style={styles.container}>
<GoogleSigninButton
style={styles.signInButton}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Dark}
onPress={() => this.signIn()}
/>
</View>
</Layout>
)
}

You are going to get the following output after this step.

Check the user’s login state

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

Add the following snippet to the render method after the Google Sign-in button display.

<View style={styles.statusContainer}>
{this.state.isLoggedIn === false ? (
<Text style={styles.message}>You must sign in!</Text>
) : (
<Button onPress={() => this.signOut()}>Sign out</Button>
)}
</View>

Here is the output after this step:

Display the user information

The final piece of the puzzle is to display the user’s 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.

Add the following code snippet after the previous section’s snippet.

<View style={styles.userInfoContainer}>
{this.state.isLoggedIn === true ? (
<>
<Text style={styles.displayTitle}>
Welcome {this.state.userInfo.user.name}
</Text>
<View style={styles.profileImageContainer}>
<Image
style={styles.profileImage}
source={{
uri:
this.state.userInfo &&
this.state.userInfo.user &&
this.state.userInfo.user.photo
}}
/>
</View>
</>
) : null}
</View>

Also, here are the complete styles:

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

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

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

On successful sign in:

That’s it. You have just learned how to implement a Google Sign-in a React Native app using Firebase.

Conclusion

In this tutorial, you learned:

That’s how you add a Login with Google feature to any React Native app or mobile app generated using the Crowdbotics App Dashboard.

Originally published on the Crowdbotics Blog April 17, 2020.

Building A Web Or Mobile App?

Crowdbotics is the fastest way to build, launch and scale an application.

Developer? Try out the Crowdbotics App Builder to quickly scaffold and deploy apps with a variety of popular frameworks.

Busy or non-technical? Join hundreds of happy teams building software with Crowdbotics PMs and expert developers. Scope timeline and cost with Crowdbotics Managed App Development for free.

--

--