Using Firestore Database with React App

Do not miss this exclusive book on Binary Tree Problems. Get it now for free.

Hello Everyone , In the previous article , we learnt about the react.js and it's basic functionalities .If you haven't read that article , you can read it here : - Basics-of-React-js.

In this article , we will build the react app which shows the visitor details and stores the visitor detail in database . For the database , we will use firebase firestore. We will add the feature to delete records in database as well.

Why ?
Because, it's easy to integrate and we can work directly on the frontend part we don't need to bother about the table , schemas or etc.
Actually Firebase firestore is the nosql datbase where the data is stored in the form of document . Document is stored inside the collection.

Are you excited 😀!! Building your first react app with firebase !!
Complete project can be found here : - Code(Github Repo)

Because I am :)

Intial Setup

So Let's start . First of all , we have to setup react app project
Open the command prompt/terminal/shell , go to the directory where you want to store your project.
In the terminal , write npm i create-react-app visitor-detail
Now open the vistor-detail folder in code edito(I like visual studio code).

Your project structure look like this .

in the terminal do cd visitor-detail and run the app using
npm start go to the browser and type localhost:3000
You will see the default react page.

Now before moving forward editing and writing code for react app . We will setup the firebase. More specific we use firebase firestore
Go to console.firebase.google.com for setting up the project and creating the app Setting Up Process

After that for initializing your app with firebase configuration.
Create the file firebase.js.

import firebase from "firebase";

export default firebase.initializeApp({
    apiKey: <your-api-key>,
    authDomain: <your-authDomain>,
    databaseURL: <your-databaseURL>,
    projectId: <your-projectId>,
    storageBucket: <your-storageBucket>,
    messagingSenderId: <your-messagingSenderId>,
    appId: <your-appId>
});

We need firebase package to working with the files and saving in the database.
npm install firebase

For setting up the firebase firestore and more about the it .You can visit official google cloud firestore documentation : - Firebase Firestore

Visitor details API

We will use the ipapi for ip adress lookup and geolocation lookup.

Informations you get from ipapi.co are : -

asn: ""
city: ""
continent_code: "AS"
country: "IN"
country_area: 
country_calling_code: "+91"
country_capital: "New Delhi"
country_code: "IN"
country_code_iso3: "IND"
country_name: "India"
country_population: 1352617328
country_tld: ".in"
currency: "INR"
currency_name: "Rupee"
in_eu: false
ip: ""
languages: "en-IN,hi,bn,te,mr,ta,ur,gu,kn,ml,or,pa,as,bh,sat,ks,ne,sd,kok,doi,mni,sit,sa,fr,lus,inc"
latitude: 
longitude: 
org: ""
postal: ""
region: "National Capital Territory of Delhi"
region_code: "DL"
timezone: "Asia/Kolkata"
utc_offset: "+0530"
version: "IPv4"


We will make two components for VisitorDetails,ListOfVisitor.
Inside VisitorDetails will act as home page.
Now for inserting this JSON data into the firebase firestore you need to import the firebase/firestore in components/VisitorDetails/VisitorDetails.jsx.

Setting up Firestore for storing data

Apply changes and setting up security rules in firestore accordingly.
Go to console.firebase.google.com Open up your project you have created initially .

In my case i will select "codingplayground" as where I am going to use cloud firestore and saving the data :) .
Click on cloud firestore . GO to security rules and allow read and write to the database.

Working with the code

Now ,come back to components/VisitorDetails/VisitorDetails.jsx file .Here we will do all the part that is necessary to update the database and showing the user reliable information.

So after initial rendering .We will be saving the ip address and geolocation of the visitors details in the firebase firestore .

We will be using the REACT HOOKS useEffect : -
useEffect is react hooks which perform the side effect in components. At initial rendering we want to fetch the ip address and visitors details using ipapi and then we will store in the database.

import React, { useEffect, useState } from "react";
import firebase from "./firebase";
import "firebase/firestore";
export default function VisitorDetails() {
  let database = firebase.firestore();

  useEffect(() => {
    async function visitordetail() {
      const response = await fetch("https://ipapi.co/json/");
      const json = await response.json();
      console.log(typeof json);
      if (localStorage.getItem("key") === null) {
        localStorage.setItem("key", JSON.stringify(json));
        database
          .collection("visitordetails")
          .add({ json })
          .then(() => {
            console.log("Data added");
          })
          .catch((error) => console.log("Error", error));
      }
    }
    visitordetail();
  }, []);

  return <div className="App-header">Visitor Detail</div>;
}

We are using the fetch method which returns the promise , so for that we are resolving using async-await. We don't want to perform the same write operation on the database from the same user for that , we have used the localstorage and checking the condition before inserting into database.
LocalStorage is browser api which gives you to add and read the dataitem.

useEffect(()=>,[]) the function is called when the component is mounting , so at initial render we only want to call this function , that's why we have given the second argument a empty array , which is dependency array.As it is empty id does not depend on any value, props or state change.

Now, If you want to show the details of the user on the page or counting the total visitors we can useState for storing the values in state.

So the final code for showing the userdetail

import React, { useEffect, useState } from "react";
import firebase from "./firebase";
import "firebase/firestore";
export default function VisitorDetails() {
  let database = firebase.firestore();
  const [detail, setdetail] = useState({});
  useEffect(() => {
    async function visitordetail() {
      const response = await fetch("https://ipapi.co/json/");
      const json = await response.json();
      console.log(json);
      setdetail(json);
      if (localStorage.getItem("key") === null) {
        localStorage.setItem("key", JSON.stringify(json));
        database
          .collection("visitordetails")
          .add({ json })
          .then(() => {
            console.log("Data added");
          })
          .catch((error) => console.log("Error", error));
      }
    }
    visitordetail();
  }, []);
  console.log(detail);

  return (
    <div className={classes.app}>
      <div className={classes.appheader}>Visitor Detail</div>
      <div className={classes.container}>
        <span>City Name : - {detail?.city}</span>
        <span>Country Name : - {detail?.country_name}</span>
        <span>IP address : - {detail?.ip}</span>
        <span> Postal : - {detail?.postal}</span>
      </div>
    </div>
  );
}

export default VisitorDetails;

Finally our app will look like this : -

Now we will add two more functionalities

  1. Delete button for deleting the visitor his/her own details .
  2. Add another component showing all visitor lists.

VisitorDetails component and we will add delete button functionality.


import React, { useEffect, useState } from "react";
import firebase from "../../firebase";
import "firebase/firestore";
import classes from "./VisitorDetails.module.css";
function VisitorDetails() {
  let database = firebase.firestore();
  const [detail, setdetail] = useState({});
  useEffect(() => {
    async function visitordetail() {
      const response = await fetch("https://ipapi.co/json/");
      const json = await response.json();
      setdetail(json);
      if (localStorage.getItem("key") === null) {
        localStorage.setItem("key", JSON.stringify(json));
        database
          .collection("visitordetails")
          .add({ json })
          .then((docRef) => {
            localStorage.setItem("docid", docRef.id);
          })
          .catch((error) => console.log("Error", error));
      }
    }
    visitordetail();
  }, []);

  const deleteItems = () => {
    let db = firebase.firestore();
    let docid = localStorage.getItem("docid");
    if (docid === null) {
      alert("already deleted");
    } else {
      db.collection("visitordetails")
        .doc(docid)
        .delete()
        .then(() => {
          setdetail({});
          localStorage.removeItem("docid");
          localStorage.removeItem("key");
          alert("detail deleted");
        })
        .catch((err) => {
          console.log(err);
        });
    }
  };

  return (
    <div className={classes.app}>
      <div className={classes.appheader}>Visitor Detail</div>
      <div className={classes.container}>
        <span>City Name : - {detail?.city}</span>
        <span>Country Name : - {detail?.country_name}</span>
        <span>IP address : - {detail?.ip}</span>
        <span> Postal : - {detail?.postal}</span>
      </div>
      <div className={classes.delete}>
        <button onClick={deleteItems}>
          Delete{" "}
          <img
            src="https://img.icons8.com/dusk/64/000000/delete-forever.png"
            width="100"
          />
        </button>
      </div>
    </div>
  );
}

export default VisitorDetails;



We have added the button when onClick , we are calling the function deleteItems in which we are seeing the document id from the localStorage and performing the deletion option .
For showing the visitor list ,we will create another folder inside components that is ListOfVisitor inside that create file ListOfVisitor.jsx.For importing the css , you can copy the css file from here : - CSS code
For showing the detail we will use this code :-

import React, { useEffect, useState } from "react";
import firebase from "../../firebase";
import "firebase/firestore";
import classes from "./ListOfVisitor.module.css";
export default function ListOfVisitor() {
  let database = firebase.firestore();
  const [vlist, setVlist] = useState([]);
  useEffect(() => {
    database
      .collection("visitordetails")
      .get()
      .then(function (querySnapshot) {
        let a = [];
        querySnapshot.forEach(function (doc) {
          a.push(doc.data().json);
        });
        setVlist(a);
      });
  }, []);

  return (
    <div className={classes.container}>
      {vlist.map((detail) => {
        return (
          <div className={classes.box}>
            <span>City Name : - {detail?.city}</span>
            <span>Country Name : - {detail?.country_name}</span>
            <span>IP address : - {detail?.ip}</span>
            <span> Postal : - {detail?.postal}</span>
          </div>
        );
      })}
    </div>
  );
}

what we are doing here ,we are retrieving the all the documents from firebase using collection name visitordetails.Then pusing the details (objects) in array and setting the state .

Now come back to App.js file we will add the routing.For routing ,we will use react-router-dom Navigating between different components.
In the terminal : -
npm install react-router-dom
Now in the app.js file we will add this code. : -

import React from "react";
import ListOfVisitor from "./components/ListOfVisitor/ListOfVisitor";
import VisitorDetails from "./components/VisitorDetails/VisitorDetails";
import { BrowserRouter, Route } from "react-router-dom";
import Navbar from "./components/Navbar/Navbar";
export default function App() {
  return (
    <div>
      <BrowserRouter>
        <Navbar />
        <Route exact path="/" component={VisitorDetails} />
        <Route exact path="/list" component={ListOfVisitor} />
      </BrowserRouter>
    </div>
  );
}

BrowserRouter: - A that uses the HTML5 history API (pushState, replaceState and the popstate event) to keep your UI in sync with the URL.

in the code you can see the Navbar component . We will add this component for navigating between the component by clicking on the link : -
Inside : components create folder Navbar and inside that add Navbar.jsx
Add this: -

import React from "react";
import { Link } from "react-router-dom";
import classes from "./Navbar.module.css";
export default function Navbar() {
  return (
    <div className={classes.nav}>
      <Link to="/">
        <div className={classes.ms}>Visitor Details</div>
      </Link>
      <Link to="/list">
        <div className={classes.ms}>Visitor List</div>
      </Link>
    </div>
  );
}

Wohoo !!

Our react web app has been completed now . Take a cofee and share the article with your friends .
You can also check this deployed app link : - Deployed Project

Github link : - Github

Don't forget , Always keep learning !! :)

Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.