Using Firebase in React Native App
Tags: reactnative, firebase, react, mobile
Published: 2021-06-24 07:37:53

*react-native v0.64, @react-native-firebase v12.1, @react-native-google-signin/google-signin v6.0*

Recently, i got a chance to build a mobile application which uses firebase as it's backend. I used firebase for google authentication and storing data in firestore. In this article, i will mainly focus on adding auth flow in Android app using react-native.

##### *Prerequisite*
I assume that we have already bootstrapped react native app using react-native-cli and configured everything needed to run a react native application. Please follow [react native docs](https://reactnative.dev/docs/environment-setup) for set up.

### Change package name for android
#### *Why is it needed* 
By default, react native cli creates application with android package `com.<project-name>`. This package name could be pretty common and can give error when adding SHA1 key in firebase. So it would be good to rename package name to something unique by adding a namespace in between i.e. `com.<company-name>.<project-name>`
Please follow this wonderful [article](https://dev.to/karanpratapsingh/quick-guide-for-updating-package-name-in-react-native-3ei3) written by @karanpratapsingh . 
Your app should run without any issue after making these changes.

### Install NPM module for firebase and google signin
We need to install two library to get Google sign in working:

* @react-native-firebase/app, @react-native-firebase/auth
* @react-native-google-signin/google-signin

#### [@react-native-firebase](https://rnfirebase.io/) vs [firebase-web-sdk](https://firebase.google.com/docs/web/setup)
If you google about the firebase google auth with react-native, almost all results will be using @react-native-firebase library for integrating firebase in react-native app. But this library is not official library from firebase. Firebase provides SDKs for web, android and IOS. So Ideally, we should be using web SDK in our react-native app and it will work without any problem. But there are few factor because of which @react-native-firebase is preferred.
* firebase web SDK doesn't support all APIs supported by native SDKs due to browser limitations.
* firebase web SDK will get executed in JS thread but since @react-native-firebase uses native SDK under hood, it would be more performant.
* To configure web SDK, we need to put keys in JS but with @react-native-firebase we need to download google.json and put it inside application code i.e. inside android directory.

#### [@react-native-google-signin/google-signin](https://github.com/react-native-google-signin/google-signin) for Google Auth
react-native-google-sign is a library which is in maintenance mode but seems pretty stable for implementing google auth with @react-native-firebase library. Since @react-native-firebase library uses native SDKs so we would need google sign native SDKs functionality exposed for react native application. That is why we have to use @react-native-google-signin library(*that's my assumption*). firebase web SDK gives methods for google auth via redirection or opening a pop-up but those methods wont be good for native application. @react-native-google-signin library opens a native pop-up for google authentication.

#### Configure app in firebase console
* login to [firebase console](https://console.firebase.google.com/)
* Create new project by clicking on "Add Project" and provide project name

*Based on project name, firebase gives a unique project identifier, generally appending numeric sequence at the end of name. If you are going to host your project on firebase (in case of web application) then this unique project identifier will become part of your application url. You can change the identifier as per your choice but it has to be unique.*
* Next page will show options to enable or disable other google services like google analytics etc.. for your application.
* That's it. New project is firebase is created.

##### Set up authentication in firebase
* Go to authentication section from left menu and click "Get Started" button
* Choose "Google" as sign-in method and enable it by clicking on edit icon.
* Also provide public facing name of your app. This will be shown to user at the time of login
* Also provide support email.
* That's it to enable google sign in.

##### Set up android application in firebase console
* Go to "Project Overview" aka home from left menu and add android app
* It will open a wizard where you need to provide package name and app name(optional)
* Also we need to provide generated SHA1 key in project to configure our project to use google auth

##### Generate signing SHA1 key
* When we bootstrapped our application with react-native cli, a debug.keystore file is also generated in android/app folder. gradle build has a task **signingReport** to generate signing keys. This task uses configuration present in build.gradle to identfy keystore file, key passowrd, store password and use it to generate SHA1 encrypted keys.
* If you want to generate keystore file then keytool cli is available to generate keystore file. You need to provide passwords to generate keystore file. Generated keystore file can be used to generate SHA1 signing key.
* Gradle build task generate SHA1 keys for different variant. **debugAndroidTest** variant should be used for the development of application.

#### Download google-services.json
After adding above information in firebase project. Next step is to download `google-services.json` file and put it in android/app location. This file contains information about clientId etc.. Native firebase SDK uses this file to make authenticated request to firebase service.
#### Configure android project for firebase
* Go to `/android/build.gradle` and add
```
dependencies {
    // ... other dependencies
    classpath 'com.google.gms:google-services:4.3.8'
    // Add me --- /\
  }
```
* Go to `/android/app/build.gradle` and add
```
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services' // <- Add this line
```

#### Initialise @react-native-google-signin
Before using any method from google-signin library, first we need to configure it by passing webClientId to configure method
```
import { GoogleSignin } from '@react-native-google-signin/google-signin';

GoogleSignin.configure({
  webClientId: '',
});
```
webClientId can be found in google-services.json file at `client/oauth_client/client_id` node

#### Login button click handler
```
import auth from '@react-native-firebase/auth';
import { GoogleSignin } from '@react-native-google-signin/google-signin';

async function onGoogleButtonPress() {
  // Get the users ID token
  const { idToken } = await GoogleSignin.signIn();

  // Create a Google credential with the token
  const googleCredential = auth.GoogleAuthProvider.credential(idToken);

  // Sign-in the user with the credential
  return auth().signInWithCredential(googleCredential);
}
```
In above code google-signin library will open the google sign pop up and on successful login returns an object containing idToken. This idToken is used to login to firebase project.
We can divide the complete auth flow in two parts:
* Google login (*performed by google-singin library*)
* Login in our application using successful google login token (*performed by auth library of react-native-firebase*)

#### AuthStateChange listener
On successful login to firebase application, authStateChange event will be triggered and our listener will get current user's info.

That's how we can configure react-native application with firebase and implement google sign in flow.