Email and Password Based Authentication with Expo and Firebase Part 1: Project Setup

diegocasmo

Diego Castillo

Posted on August 29, 2021

Email and Password Based Authentication with Expo and Firebase Part 1: Project Setup

For a while now, I've been using Firebase as my go-to tool to quickly setup an email and password based authentication flow when working with Expo. While there are many other solutions out there, I've yet to find one that allows me to get started so quickly as Firebase does.

The goal of this series of blog posts, is to provide a simple example of how to setup Expo and Firebase with email and password based authentication. When done, this app will support sign up, sign in, sign out, email verification, forgot password, and update password. All the code for this series of blog posts is available on this Github repository. Let's jump right in.

Create a New Expo App

If not done already, install the Expo CLI by running npm install --global expo-cli so that the application can be created. Next, create a new application by running expo init --npm and select the blank template. The application can now be served with npm start and opened locally or in the device/simulator of your preference. For simplicity, I'll be running it through React Native for web, which works out of the box with the Expo SDK. To do so, simply press w in the terminal that's running the Expo CLI.

expo-cli-optionsExpo CLI options to open an app.

Assuming everything went smoothly, the newly created Expo app should now be accessible via a web browser in http://localhost:19006/, where it should display a familiar welcome message.

Create a Firebase Project

Navigate to your Firebase account and create a new project. Once the project is created, click in the sidebar "Authentication" menu item, and enable the "Email/Password" provider.

firebase-email-provider-enabled"Email/Password" Firebase authentication provider enabled.

Next, go to the project settings and register a web app for the project.

firebase-register-web-appSelect the web app platform to register the web app.

Finally, add the Firebase SDK to the web app (this configuration will later on be used to initialize the Firebase app in the Expo project).

firebase-sdk-configuration-exampleFirebase SDK configuration example.

Configure Expo and Firebase

It's time to use the Firebase project configuration in the Expo app. To do so, first install the Firebase SDK by running expo install firebase. Additionally, install react-native-dotenv by running npm install react-native-dotenv, so that environment variables can be imported in the app via an .env file. Next, add the module:react-native-dotenv plugin to the default Expo babel.config.js file.

module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: [
      ['module:react-native-dotenv'], // Add this
    ],
  };
};
Enter fullscreen mode Exit fullscreen mode


babel.config.js configuration file.

Create an .env file in the root directory of the project by running touch .env, and fill it in with the correct Firebase SDK configuration details. I've prefixed them with FIREBASE_ so that it's clear what these are for.

FIREBASE_API_KEY=
FIREBASE_AUTH_DOMAIN=
FIREBASE_PROJECT_ID=
FIREBASE_STORAGE_BUCKET=
FIREBASE_MESSAGING_SENDER_ID=
FIREBASE_APP_ID=
Enter fullscreen mode Exit fullscreen mode


Example of an .env file. Fill it in with the Firebase SDK web app project configuration.

Create the app's API directory by running mkdir -p src/api and an index file within it with touch src/api/index.js. This is where the Firebase app will be initialized. To do so, use the environment variables.

import firebase from 'firebase';
import {
  FIREBASE_API_KEY,
  FIREBASE_AUTH_DOMAIN,
  FIREBASE_PROJECT_ID,
  FIREBASE_STORAGE_BUCKET,
  FIREBASE_MESSAGING_SENDER_ID,
  FIREBASE_APP_ID,
} from '@env'

const firebaseConfig = {
  apiKey: FIREBASE_API_KEY,
  authDomain: FIREBASE_AUTH_DOMAIN,
  projectId: FIREBASE_PROJECT_ID,
  storageBucket: FIREBASE_STORAGE_BUCKET,
  messagingSenderId: FIREBASE_MESSAGING_SENDER_ID,
  appId: FIREBASE_APP_ID,
};

firebase.initializeApp(firebaseConfig);
Enter fullscreen mode Exit fullscreen mode

Finally, import this file in App.js (located in the root directory):

import './src/api'; // Import the Firebase API configuration file
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

// Rest of the file omitted...
Enter fullscreen mode Exit fullscreen mode

Application Structure and Dependencies

To simplify the application, I'll be using the following libraries (installation instructions are outlined below each of them). Note that none of these libraries are technically required, but they will simplify getting up and running.

  • NativeBase: mobile-first, accessible components for React Native & Web.

    npm install native-base styled-components styled-system
    expo install react-native-svg
    expo install react-native-safe-area-context
    
  • Formik: create forms, manage, and validate their state.

    npm install formik
    
  • Yup: schema builder for value parsing and validation (which integrates nicely with Formik).

    npm install yup
    
  • React Navigation: routing and navigation for Expo and React Native apps.

    npm install @react-navigation/native
    expo install react-native-screens react-native-safe-area-context
    

Let's now create the "application structure". The application structure will use a "feature-based" approach, where each feature (i.e., sign up, email verification, etc) will be contained within a directory.

src/
  Root.js
  api/ # API-only methods (Firebase)
  components/ # Re-usable components (among many features)
  features/
    sign-up/
      components/ # Components used by the sign-up feature only
      screens/ # Container type component(s) which setup layout/structure and higher level logic
Enter fullscreen mode Exit fullscreen mode

The first step is to create the Root.js file. To do so, copy App.js by running cp App.js src/Root.js, then remove App.js (rm App.js), and update the package.json file so that main points to src/Root.js:

"main": "src/Root.js"
Enter fullscreen mode Exit fullscreen mode

Next, replace the contents of Root.js so that it imports the Firebase API, setup the native-base provider, and register the root Expo component.

import './api';
import { registerRootComponent } from 'expo';
import React from 'react';
import { StatusBar } from 'expo-status-bar';
import { NativeBaseProvider, Box } from 'native-base';

const Root = () => (
  <NativeBaseProvider>
    <Box>Hello world</Box>
    <StatusBar style="auto" />
  </NativeBaseProvider>
);

registerRootComponent(Root);
Enter fullscreen mode Exit fullscreen mode

Start the Expo server once again by running npm start and make sure the "Hello world" message is correctly shown.

Re-cap

In this blog post, we've gone over setting up Expo and Firebase together with the goal of implementing an email and password based authentication system. Additionally, a common set of libraries were installed and setup to make it easier to implement the upcoming features the app will need. In the next blog post, we'll implement the sign up, email verification, and sign out features.

💖 💪 🙅 🚩
diegocasmo
Diego Castillo

Posted on August 29, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related