Expo Firebase Authentication & Cloud Firestore Using async/await & React Hooks

 


Introduction

Let’s talk about setting up and authenticating a user in a relatively easy way, so as a developer, you can build the best application experience for users. As I am trying to implement the sign in and sign out features using Firebase Authentication, I find it difficult to pin down the steps. It turns out that some details are slightly different depending on what you are building. We will be walking through all the steps you needed to authenticate a user and save the user information with customized fields into Cloud Firestore using async/await syntax and React Hooks in Expo. The keyword here is Expo. Keep on reading if and only if you are developing a mobile application in Expo.

What is Firebase?

Firebase is a platform developed by Google for mobile and web application creation. It is a Back-end-as-a-Service (Baas), allowing developers to link their applications to backend cloud storage while providing additional features. The features of Firebase include authentication, cloud Firestore, real-time database, cloud functions, analytics, hosting, cloud storage, and Firebase machine learning.

What is Firebase Authentication?

Firebase Authentication is a super simple way to authenticate your user without writing much code. The built-in error message is a nice feature. It throws an easy-to-understand error message to the user. It supports various authentication methods, such as passwords, phone numbers, anonymous, popular federated identity providers like Google, Facebook, and Twitter.

What is Cloud Firestore?

Cloud Firestore is the latest real-time NoSQL database for mobile app development developed by Google. It stores data as collections of documents similar to JSON. It allows sub-collections within documents and provides various built-in query methods.

Step 1: Creating a new app using Expo CLI

If you never develop any application using Expo, I highly recommend you read this installation documentation.

  • Initializing the project

 $ expo init <YOUR_APP_NAME>
  • Installing dependencies, Expo recommends using expo install commands
$ expo install firebase$ expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view $ expo install @react-navigation/native @react-navigation/stack 

Step 2: Create a Google Firebase Account

  • Go to Firebase Console
  • Sign up an account and create a new project
  • Put in your project name, click “Continue”.
  • Disable Google analytics as this is not the focus for now.
  • Click “Create Project” it is going to take a while before it says “Your new project is ready”, click “Continue.”
  • On the Project Overview, click on the “Web” icon since we are building on Expo, then give it a name, click “Register app”, it will show you the Firebase configuration, copy the SDK keys, we will use it in the next step.
Step 3: Placing Firebase configuration in Expo project
Back to your terminal:
  • Create a “config” directory on the root of your project
  • Create a “keys.js” file under the “config” directory
  • Copy and paste the Firebase configuration to “key.js”, export it, we will import it later to initialize the Firebase connection in Step 6
  • Make sure you do not upload the “keys.js” file to GitHub for security reasons, instead place it on the “.gitignore” file
“YOUR_APP_NAME/config/keys.js”


“YOUR_APP_NAME/.gitignore”

Step 4: Configure Firebase Console Sign-In Methods and Firestore

In this example, we will enable one sign-in method only. Feel free to enable more as needed. Once you enable the option and provide all the necessary front-end form or button, the user can sign in with many different methods. For example, if you allow the “Anonymous” sign-in method, the user can access the application without signing in.

Back to Firebase Console:
  • On “Project Overview”, click the “Authentication” on the left sidebar.
  • Click on the second tab where it said “Sign-In method
  • Enable all the Sign-in method you would like to enable. For now, we will enable the “Email/Password” option.
  • We will then click the “Cloud Firestore” on the left to create a database.
  • Select the “Start in test mode” option, click “next.”
  • Select the “Cloud Firestore location”, click “Enable

Step 5: Create an API folder for all Firebase related methods

Let’s create an “API” folder on the root and use touch to create the file that contains all Firebase methods, and we will go over each of the function on this gist:

Registration:
  • The registration function takes in four arguments from “SignUp.js
  • createUserWithEmailAndPassword() requires two arguments, email, and password, to create an account for the user on the “Authentication” of your Firebase Console. It automatically assigns a unique UID to identify each user.
  • firebase.firestore().collection('users') create a collection ( a.k.a. tables or models) called “users”
  • The .doc(uid) on line 12 create a document (a.k.a an entry or instance) that contains a unique ID(uid) from the “Authentication”
  • The .set() on line 13 represents the customized field (i.e., column name or attribute) for the collection. It can be any information that you wish to collect from your user. Note that this method takes in the field and its value as a key-value pair.
  • In this example, we collected the email, first name, and last name of the user.
Sign In:
  • The sign-in function takes in two arguments from “SignIn.js”
  • The firebase.auth.signInWithEmailAndPassword() method validate a user through Firebase Authentication
  • Note that you can only get the user’s UID since it does not look up any information from the Cloud Firestore “users” collection.
  • If you would like to retrieve a customized field in the collection, please refer to the “Dashboard.js” on Step 8
Sign Out:
  • The sign-out function is invoked when the user pressed the “Sign Out” button on “Dashboard.js” using firebase.auth.signOut()
Let me walk through the user experience before we dive into the details for each of the screens.
  • Users will first see the “Loading” screen, and they will be landing on “Home” screen if they are not signed in or “Dashboard” if they are signed in.
  • For users that have not set up an account with the app, the “Sign Up” button will take them to the “Sign Up” screen. Once signed up, they will be diverted to the “Dashboard” screen.
  • Users that have an account but are not signed in can do so by clicking the “Sign In” button. They will be redirected to the “Dashboard”, where they will see their name and the “Sign out” button.
From this step onward, I would highly recommend you tested each of the screens to make sure it is bug-free before adding another screen by adding the screen one at a time to “App.js” in the next step.

Step 6: “App.js” Firebase Initialization & Stack Screens

We will initialize Firebase on “App.js” using the SDK we stored in “keys.js” on Step 3 as shown on this gist:
  • The if statement on line 15 is checking the Firebase app was not called anywhere else before the initialization

Step 7: Home Screen for Sign In and Sign Up

Any users that are not signed in will be redirected to the “Home” screen after seeing a flash of the loading screen, as shown in this gist. The user has the option to sign up or sign in.

Step 8: Customize Sign Up Form

This screen contains a sign-up form containing fields you would like to collect from your user and store it in Cloud Firestore. After the user puts in all the required information, their entered information will be passed in as arguments for the “registration” function defined in Step 5. Again, it is a two-step process to utilize Firebase Authentication for user credential validation and Cloud Firestore for customized fields. Here is the gist for the “Sign Up” screen. Don’t be tempted to press the sign-up button as the “Loading” and “Dashboard” screen are not yet ready.

Step 9: Dashboard and Sign Out Button

Upon successful sign-in or sign-up, users will be redirected to the “Dashboard” screen to view their profile information and sign-out. Note that we are retrieving data from the Cloud Firestore using the query method on line 13 through line 17. The firebase.auth().currentUser allows identification of the currently signed-in user. In this example, we display the first name only, and you can always get more information depending on your needs. Just keep in mind you are retrieving the data as a key-value pair, as shown on line 22, “dataObj” of the gist.

Step 10: Loading Screen for Listening Current User

The “Loading” screen has important .onAuthStateChanged() method provided by Firebase Authentication that allows continuous to the current user. This is the first screen that any user will encounter. An authenticated user of the app will be directed to their dashboard while others will be directed to the “Home” screen. You can now try to sign up for an account and see your first name displayed on the dashboard. We have one more screen to set up.

Step 11: Sign In Screen

The “Sign In” screen is short and simple. Once the user entered their email and password, pass them down to the “signIn” function imported from Step 5, the user will be signed in via Firebase Authentication.

Conclusion

While I am reading through the documentation, the greatest challenge is which application I should follow as there are different libraries for different things. Just making sure you are using the libraries that are compatible with Expo. Not all the React Native libraries are supported in the Expo environment.

The challenge for the Firestore would be just looking at the information related to the web application icon and then check if it is compatible with Expo. Do not bother to look at iOS information, which utilized Swift, or android, which used Android Studio.

Here is the GitHub Link for this example. Feel free to reach us for any questions or comments.