Building a serverless web application with React and Firebase

Building a serverless web application with React and Firebase

what is a serverless web application?

A serverless web application is a web application built using a serverless architecture. The server-side logic is handled by a cloud provider, such as AWS, Google Cloud, or Microsoft Azure, rather than needing to set up and maintain one or more servers. In a serverless web application developers write code as functions that are triggered by events such as HTTP requests or changes to a database.

Prerequisites

Before you get started, make sure you have the following installed:

  • Node.js (version 10 or higher)

  • npm or yarn

  • Firebase SDK (you can install it by running "npm install firebase" or "yarn add firebase" in your terminal)

Set up a Firebase project

The first step is to create a Firebase project and enable the services you need. follow these steps:

  1. Go to Firebase and click on "Go to console"

  2. Click "Add project" to create a project

  3. Once the project is created, click on "add Firebase to your web app" and follow the prompts to set up Firebase Hosting, Authentication, and Cloud Firestore.

  4. copy the configuration code that appears because you will need it in your React application

Create a React project

Now that you have a Firebase project setup it's time to create a React application using Vite, follow these steps:

  1. if you are using npm, open your terminal and run "npm create vite@latest react-firebase-app" to create a new React app. If you are using yarn run "yarn create Vite react-firebase-app" instead.

  2. Once the app is created, navigate to its directory by running "cd react-firebase-app".

  3. Run "npm run dev" if you are using npm or "yarn run dev" if you are using yarn to start the development server.

  4. open your localhost in your browser to see the app running.

Connect your react app to Firebase

To connect your React app to Firebase, follow these steps:

  • In your React app directory run "npm install firebase" if you are using npm or run "yarn add firebase" if you are using yarn to install the firebase sdk

  • Create a new file called "firebase.jsx" in your src directory. note that if you used Vite to create your application you would be using ".jsx" instead of ".js"

  • To configure Firebase, you need to add the Firebase configuration code you copied earlier to the "firebase.jsx" file you just created. It would look like the code below.

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
  apiKey: "AIzaSyBgFxosqoGF8b9RX1ZIk_zwKI7oLFkDZok",
  authDomain: "mrdareauth.firebaseapp.com",
  projectId: "mrdareauth",
  storageBucket: "mrdareauth.appspot.com",
  messagingSenderId: "867798194052",
  appId: "1:867798194052:web:d1981f8766c25509196fd1",
  measurementId: "G-55PP94TD82"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

Importing Firebase Functions for App Features

Now that your app is connected to Firebase, you can start implementing features like user authentication, storage etc. To implement features, you would need to import some functions from Firebase. The code below shows how you can import the authentication and storage feature functions. (Note that you would import them in your 'firebase.jsx' file)

import {getAuth} from "firebase/auth"
import {getFirestore} from "firebase/firestore"

After importing the functions you can then wrap the app variable in them and assign them to a variable so that they can be exported and used in other components. the code below shows how it would look like

const auth = getAuth(app) //initializes the Firebase Authentication service for your app
const db = getFirestore(app) //initializes the Firebase firestore service for your app

export {auth, db} //export auth and db so that it can be used in other components

After doing all of that, your code should look like the code below

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import {getAuth} from "firebase/auth"
import {getFirestore} from "firebase/firestore"

const firebaseConfig = {
  apiKey: "AIzaSyBgFxosqoGF8b9RX1ZIk_zwKI7oLFkDZok",
  authDomain: "mrdareauth.firebaseapp.com",
  projectId: "mrdareauth",
  storageBucket: "mrdareauth.appspot.com",
  messagingSenderId: "867798194052",
  appId: "1:867798194052:web:d1981f8766c25509196fd1",
  measurementId: "G-55PP94TD82"
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app)
const db = getFirestore(app)

export {auth, db}

Implement features

Now that you have imported the functions and initialized the Firebase services for your app, you can start using them in your React application.

Authentication

To use the authentication service, create a new file called "auth.jsx". The Firebase authentication service provides different ways to authenticate your user but to use the email and password method, import usestate and useEffect from React, "auth" from "firebase.jsx", and some relevant authentication functions from the Firebase library. It should look like the code below

import {useState, useEffect} from 'react'
import {auth} from './firebase'
import {createUserWithEmailAndPassword, signInWithEmailAndPassword, onAuthStateChanged, signOut} from 'firebase/auth'

After importing the necessary functions you can then go on to write the authentication code which would look like the code below

import {useState, useEffect} from 'react'
import {auth} from './firebase'
import {createUserWithEmailAndPassword, signInWithEmailAndPassword, onAuthStateChanged, signOut} from 'firebase/auth'

export const Auth = () => {
    const [currentUser, setCurrentUser] = useState('')

    useEffect(()=> {
       onAuthStateChanged(auth, (user)=> {
         if(user){
           setCurrentuser(user)
         }else {
           setCurrentuser(null)
         }
       })
     },[])

    const handleSignup = async () => {
       try {
          const { user } = await createUserWithEmailAndPassword(
            auth, 
            email, 
            password
           )
        } catch (error) {
           console.log(error)
        }
     }

    const handleLogin = async () => {
       try {
          const { user } = await signInWithEmailAndPassword(
            auth, 
            email, 
            password
           )
        } catch (error) {
           console.log(error)
        }
     }

    const logOut = async () => {
      await signOut(auth)
      setCurrentuser(null)
    }
}

In the code above, The useState hook is used to store the current user, while the useEffect hook with onAuthStateChanged listens for changes in the authentication state and allows you to keep track of the current user's authentication status, such as when a user logs in or logs out and it updates the currentUser state accordingly.

The handleSignup and handleLogin functions use the createUserWithEmailAndPassword and signInWithEmailAndPassword functions to create new users and sign in existing ones using their email and password.

The auth provides methods for user authentication and management, such as creating a new user account, signing in with an existing account, and signing out. It is passed as an argument to the onAuthStateChanged, createUserWithEmailAndPassword, signInWithEmailAndPassword, and signOut methods to perform user authentication and management operations.

The logOut function uses the signOut function to sign out the current user and set currentUser state to null.

Firestore Database

Firestore is a NoSQL database offered by Firebase that allows developers to store and manage data for their web or mobile applications. To use the Firestore database service, create a file called "data.jsx". Import usestate and useEffect from React, "db" from "firebase.jsx", and some relevant authentication functions from the Firebase library. It should look like the code below

import {db} from './firebase'
import {addDoc, collection, doc, deleteDoc} from 'firebase/firestore'

After importing the necessary functions you can then go on to write the code to use them to interact with the Firestore database. It should look like the code below

import {db} from './firebase'
import {addDoc, collection, doc, deleteDoc} from 'firebase/firestore'

export const Data = () => {
//function to add a data to firebase database
    const handleSubmit = async() => {
      try {
        await addDoc(collection(db, 'info'), {
          name: 'Fran'
          age: 21
          id: 'vssf2y2fwh2tiuy'
        })  
      }catch (error){
          console.log(error)
      }
    }

//function to delete a data from firebase
    const handleDelete = async() => {
      try {
        await deleteDoc(doc(db, 'info', id)           
      }catch (error){
         console.log(error)
      }
    }
}

The code above consists of two functions: handleSubmit and handleDelete.

handleSubmit uses the addDoc function to add a new document to the 'info' collection in the Firestore database. The addDoc function takes two arguments: the first argument is a reference to a Firestore collection (in this case, 'info'), and the second argument is an object containing the data to be added to the database.

So in this case, the handleSubmit function is adding a new document with the data: { name: 'Fran', age: 21, id: 'vssf2y2fwh2tiuy' } to the 'info' collection.

The handleDelete function on the other hand deletes a document in the collection. It uses the deleteDoc function to delete a document in the 'info' collection in the Firestore database. the deleteDoc function takes a doc reference as its argument. In this case, the reference is created using the doc function, which takes three arguments: a reference to the Firestore database, the name of the collection (in this case, 'info'), and the id of the document to be deleted.

Note that there are other things you could also do with the Firestore such as update, as well as listen for real-time updates to your data. You can also use Firestore to query your data, combine and filter data from multiple collections, and perform advanced queries.

Conclusion

In conclusion, this article has covered the basics of building a serverless React application with Firebase. We have seen how Firebase provides us with a powerful suite of tools that allow us to quickly and easily build web applications. However, this is just the beginning, as Firebase offers many other features and services that we have not had a chance to explore in this article. I hope this article has provided a helpful introduction to building serverless React applications with Firebase. Happy coding!