Reactjs CRUD Firebase Realtime Database Example

Reactjs Firebase CRUD Realtime database Example

Tutorial: “Reactjs CRUD Firebase Realtime Database Example”

The Firebase Realtime Database is a cloud-hosted NoSQL database that lets you store and sync data between your users in realtime. In the tutorial, I introduce how to build an “Reactjs CRUD Firebase Realtime Database Example ” project to do CRUD operation: POST/GET/PUT/DELETE requests with step by step coding examples.

– I draw a fullstack overview diagram architecture from Reactjs frontend to Firebase Realtime Database.
– I illustrate details about react-firebase CRUD operations.
– I implement Reactjs application to do CRUD request (Post/Get/Put/Delete) to Firebase Realtime database.

Related posts:


Overview Architecture Diagram – Reactjs CRUD Firebase Realtime Database

Reactjs Firebase Realtime Database CRUD Overview Architecture Diagram
Reactjs Firebase Realtime Database CRUD Overview Architecture Diagram

Reactjs CRUD Application is designed with 2 main layers:

– React.js components let you split the UI into independent, reusable pieces, and think about each piece in isolation.
– Firebase Service is used by above React Components to fetch (Post/Put/Get/Delete) data to Firebase Realtime database.

Reactjs CRUD Application defines 5 components:

  • Home.js is used serve as the landing page for your app.
  • AppNavbar.js is used to establish a common UI feature between components.
  • CustomerList.js is used to show all customers in the web-page
  • CustomerEdit.js is used to modify the existed customer
  • App.js uses React Router to navigate between components.

Integrative Project Goal between Reactjs CRUD Firebase Realtime Database

Reactjs Home page:

Project Goal Home Page
Project Goal Home Page

Reactjs List all data:

Reactjs show list customers after doing CRUD operations
Reactjs show list customers after doing CRUD operations

Reactjs add data:

Project Goal Reactjs Add a Customer to Realtime Database of Firebase
Project Goal Reactjs Add a Customer to Realtime Database of Firebase

Reactjs update data:

Project Goal Reactjs Update Customer to Firebase
Project Goal Reactjs Update Customer to Firebase

Reactjs delete a customer with id=2, check the Customer List after deleting:

Reactjs show list customers after doing CRUD operations
Reactjs show list customers after doing CRUD operations

Check Firebase Database after do CRUD operations:

Firebase realtime datatbase - after deleting a customer
Firebase realtime datatbase – after deleting a customer

Firebase Realtime Database CRUD Operation

Set up the Firebase Project

To setup Firebase Realtime Database project, you can follow the guide at here.

Register-Firebase-Successfully
Register-Firebase-Successfully

Firebase Realtime database CRUD operations guidelines

We use instance of firebase.database.Reference to read/write data from the Firebase database.

const customerRef = firebase.database().ref('/customers');

Firebase Realtime Database – Read operation

– Read list once using once():

customerRef.once('value', (snapshot) => {
  let customers = [];

  snapshot.forEach( (childSnapshot) => {
    var key = childSnapshot.key;
    var data = childSnapshot.val();
    // ...

    customers.push({ key: key, firstname: data.firstname, ...});
  });
});

– Read List with listening to the data changes using on():

customersRef.on('child_added', (data) => {
   // data.key, data.val().firstname, data.val().lastname, ...
});

customersRef.on('child_changed', (data) => {
  // data.key, data.val().firstname, data.val().lastname, ...
});

customersRef.on('child_removed', (data) => {
  // data.key, data.val().firstname, data.val().lastname, ...
});

– Listening for all value events on a List reference

let onDataChange = customersRef.on('value', (snapshot) => {
  snapshot.forEach( (childSnapshot) => {
    let childKey = childSnapshot.key;
    let childData = childSnapshot.val();
    // ...
  });
});

– Remove the listener using off():

customersRef.off("value", onDataChange);

Firebase Realtime Database Create operation

– Create a new object in List:

customersRef.push({
  firstname: "Jack",
  lastname: "Smith",
  ...
});

Firebase Realtime Database Update operation

– Update object in List:

* destructive update using set(): delete everything currently in place, then save the new value

customersRef.child(key).set({
  firstname: "Jack",
  lastname: "Smith",
  ...
});

* non-destructive update using update(): only updates the specified values

customersRef.child(key).update({
   firstname: "Jack",
});

Firebase Realtime Database Delete operation

– Delete an object in List:

customersRef.child(key).remove();

– Delete entire List:

customersRef.remove();

Implement Reactjs CRUD Firebase Realtime Database

Overview Reactjs CRUD Application with Firebase Realtime Database

Reactjs Project structure:

Reactjs CRUD Project Structure
Reactjs CRUD Project Structure

Reactjs architecture diagram:

Reactjs Firebase Realtime Database CRUD Overview Architecture Diagram
Reactjs Firebase Realtime Database CRUD Overview Architecture Diagram

For more details, we go back to the session: Overvier Architecture Diagram – Reactjs CRUD Firebase Realtime Database

How to build Reactjs CRUD Firebase Application?

We build a Reactjs Application to fetch data from Firebase Realtime Database with 5 UI components and a service. Step to do:
– Setup Reactjs Application
– Add Firebase configuration to Reactjs environments
– Implement Reactjs CRUD Firebase Service
– Build Reactjs Navigation Bar component
– Build Reactjs Home page component
– Build Reactjs CustomerList Component
– Build Reactjs CustomerEdit Component
– Update Reactjs App.js Component with Router

Setup Reactjs Application with firebase

Create React App is a command line utility that generates React projects for you. It’s a convenient tool because it also offers commands that will build and optimize your project for production.
The create-react-app will set up everything you need to run a React application.

– Create a new project in the app directory with Yarn.

yarn create react-app app

After the app creation process completes, navigate into the app directory and install Bootstrap, cookie support for React, React Router, and Reactstrap.

Reactstrap: This library contains React Bootstrap 4 components that favor composition and control. The library does not depend on jQuery or Bootstrap javascript.
– React Router: Components are the heart of React’s powerful, declarative programming model. React Router is a collection of navigational components that compose declaratively with your application.

cd app
yarn add bootstrap@4.1.3 react-cookie@3.0.4 react-router-dom@4.3.1 reactstrap@6.5.0

Import, we install firebase to reactjs project by cmd:

$npm i firebase

Add Firebase configuration to Reactjs environments variable

– Create a file ./src/util/firebase.js to add firebase configuration as below content:

import firebase from "firebase";

let firebaseConfig = {
    apiKey: "AIzaSyBVm7nQJqpJxXMr63spZydivMPgoECs_R0",
    authDomain: "loizenai-reactjs-crud-db.firebaseapp.com",
    projectId: "loizenai-reactjs-crud-db",
    storageBucket: "loizenai-reactjs-crud-db.appspot.com",
    messagingSenderId: "610864533391",
    appId: "1:610864533391:web:c3adddd2aa1ac818fe45fa",
    measurementId: "G-LD2JGWF657"
  };

// Initialize Firebase
firebase.initializeApp(firebaseConfig);
export default firebase.database();
Register-Firebase-Successfully
Register-Firebase-Successfully

Implement Reactjs CRUD Firebase Service: Post/Get/Put/Delete operations

Implement a FirebaseService in file ./src/services/FirebaseService.js as below:

import firebase from '../util/firebase';

const db = firebase.ref('/customers');
let customers = [];

class FirebaseService {
  
  addCustomer = (customer) => {
    db.push(customer);
  };

  getAll() {
    return db;
  }

  get(key) {
    return db.child(key);
  }

  update(key, value) {
    return db.child(key).update(value);
  }

  delete(key) {
    return db.child(key).remove();
  }
}

export default new FirebaseService();

Implement Reactjs CRUD Components

Build Application Navigation Bar Component

import React, { Component } from 'react';
import { Collapse, Nav, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';
import { Link } from 'react-router-dom';

export default class AppNavbar extends Component {
  constructor(props) {
    super(props);
    this.state = {isOpen: false};
    this.toggle = this.toggle.bind(this);
  }

  toggle() {
    this.setState({
      isOpen: !this.state.isOpen
    });
  }

  render() {
    return <Navbar color="dark" dark expand="md">
      <NavbarBrand tag={Link} to="/">Home</NavbarBrand>
      <NavbarToggler onClick={this.toggle}/>
      <Collapse isOpen={this.state.isOpen} navbar>
        <Nav className="ml-auto" navbar>
          <NavItem>
            <NavLink
              href="https://loizenai.com">loizenai.com</NavLink>
          </NavItem>
          <NavItem>
            <NavLink href="https://github.com/loizenai">GitHub</NavLink>
          </NavItem>
        </Nav>
      </Collapse>
    </Navbar>;
  }
}

Create Reactjs Home Page Component

Project Goal Home Page
Project Goal Home Page
import React, { Component } from 'react';
import './App.css';
import AppNavbar from './AppNavbar';
import { Link } from 'react-router-dom';
import { Button, Container } from 'reactstrap';

class Home extends Component {
  render() {
    return (
      <div>
        <AppNavbar/>
        <Container fluid>
          <Button color="link"><Link to="/customers">Manage Customer List</Link></Button>
        </Container>
      </div>
    );
  }
}

export default Home;

Build Reactjs CustomerList Component

Reactjs show list customers after doing CRUD operations
Reactjs show list customers after doing CRUD operations

– CustomerList Component will fetch a list of customers from Firebase Realtime database and then shows all of them on a Bootstrap table.
– The CustomerList has 3 buttons:

  • Add Customer & Edit are used to link to a url /customers/new that will map with CustomerEdit component
  • Delete button is used to remove a Customer entity from Firebase Realtime Database based on a given key through an async function remove(key) that will do a request with DELETE method to Firebase.

Detail coding:


import React, { Component } from 'react';
import { Button, ButtonGroup, Container, Table } from 'reactstrap';
import AppNavbar from './AppNavbar';
import { Link } from 'react-router-dom';
import FirebaseService from '../services/FirebaseService';

class CustomerList extends Component {

  constructor(props) {
    super(props);
    this.state = {customers: [], isLoading: true};
    this.remove = this.remove.bind(this);
  }

  componentDidMount = () => {
    FirebaseService.getAll().on("value", this.onDataChange);
  }

  componentWillUnmount = () => {
    FirebaseService.getAll().off("value", this.onDataChange);
  }

  onDataChange = (items) => {
    console.log(items);
    let customers = [];
    items.forEach(item => {
      let data = item.val();
      customers.push({
        key: item.key,
        firstname: data.firstname,
        lastname: data.lastname,
        address: data.address,
        age: data.age,
        copyrightby: "https://loizenai.com"
      });
    });

    this.setState({
      customers: customers,
      isLoading: false
    });
  }

  async remove(key) {
    FirebaseService.delete(key)
    .then(() => {
      let updatedCustomers = [...this.state.customers].filter(i => i.key !== key);
      this.setState({customers: updatedCustomers});
    });
  }

  render() {
    const {customers, isLoading} = this.state;

    if (isLoading) {
      return <p>Loading...</p>;
    }

    const customerList = customers.map(customer => {
      return <tr key={customer.key}>
        <td style={{whiteSpace: 'nowrap'}}>{customer.firstname}</td>
        <td>{customer.lastname}</td>
        <td>{customer.age}</td>
        <td>{customer.address}</td>
        <td><a href={customer.copyrightby}>{customer.copyrightby}</a></td>
        <td>
          <ButtonGroup>
            <Button size="sm" color="primary" tag={Link} to={"/customers/" + customer.key}>Edit</Button>
            <Button size="sm" color="danger" onClick={() => this.remove(customer.key)}>Delete</Button>
          </ButtonGroup>
        </td>
      </tr>
    });

    return (
      <div>
        <AppNavbar/>
        <Container fluid>
          <div className="float-right">
            <Button color="success" tag={Link} to="/customers/new">Add Customer</Button>
          </div>
          <h3>Customer List</h3>
          <Table className="mt-4">
            <thead>
              <tr>
                <th width="20%">Firstname</th>
                <th width="20%">Lastname</th>
                <th width="10%">Age</th>
                <th>Address</th>
                <th>Copyrightby</th>
                <th width="10%">Actions</th>
              </tr>
            </thead>
            <tbody>
            {customerList}
            </tbody>
          </Table>
        </Container>
      </div>
    );
  }
}

export default CustomerList;

Build Reactjs CustomerEdit Component

Project Goal Reactjs Update Customer to Firebase
Project Goal Reactjs Update Customer to Firebase

import React, { Component } from 'react';
import { Link, withRouter } from 'react-router-dom';
import { Button, Container, Form, FormGroup, Input, Label } from 'reactstrap';
import AppNavbar from './AppNavbar';
import FirebaseService from '../services/FirebaseService';

class CustomerEdit extends Component {

  emptyCustomer = {
    key: '',
    firstname: '',
    lastname: '',
    age: "",
    address: '',
    copyrigtby: 'https://loizenai.com'
  };

  constructor(props) {
    super(props);
    this.state = {
      item: this.emptyCustomer
    };
  }

  componentDidMount = () => {
    let key = this.props.match.params.key
    if (key !== 'new') {
      FirebaseService.get(key).on("value", this.onDataChange);
    }
  }

  componentWillUnmount = () => {
    FirebaseService.getAll().off("value", this.onDataChange);
  }

  onDataChange = (item) => {
    let data = item.val();
    let customer = {
      key: item.key,
      firstname: data.firstname,
      lastname: data.lastname,
      age: data.age,
      address: data.address,
      copyrightby: 'https://loizenai.com'
    };

    this.setState({
      item: customer,
    });
  }

  handleChange = (e) => {
    const target = e.target;
    const value = target.value;
    const name = target.name;
    let item = {...this.state.item};
    item[name] = value;
    this.setState({item});
  };

  handleSubmit = (e) => {
    e.preventDefault();
    const {item} = this.state;
    let key = this.props.match.params.key
    if (key !== 'new') {
      FirebaseService.update(key, item);
    } else {
      FirebaseService.addCustomer(item);
    }

    this.props.history.push('/customers');
  };

  render = () => {
    const {item} = this.state;
    const title = <h2>{item.key ? 'Edit Customer' : 'Add Customer'}</h2>;

    return <div>
      <AppNavbar/>
      <Container>
        {title}
        <Form onSubmit={this.handleSubmit}>
          <FormGroup>
            <Label for="firstname">Firstname</Label>
            <Input type="text" name="firstname" id="firstname" value={item.firstname || ''}
                   onChange={this.handleChange} autoComplete="firstname"/>
          </FormGroup>
          <FormGroup>
            <Label for="lastname">Lastname</Label>
            <Input type="text" name="lastname" id="lastname" value={item.lastname || ''}
                   onChange={this.handleChange} autoComplete="lastname"/>
          </FormGroup>          
          <FormGroup>
            <Label for="age">Age</Label>
            <Input type="text" name="age" id="age" value={item.age || ''}
                   onChange={this.handleChange} autoComplete="age"/>
          </FormGroup>
          <FormGroup>
            <Label for="address">Address</Label>
            <Input type="text" name="address" id="address" value={item.address || ''}
                   onChange={this.handleChange} autoComplete="address"/>
          </FormGroup>
          <FormGroup>
            <Button color="primary" type="submit">Save</Button>{' '}
            <Button color="secondary" tag={Link} to="/customers">Cancel</Button>
          </FormGroup>
        </Form>
      </Container>
    </div>
  }
}

export default withRouter(CustomerEdit);

Edit Reactjs App.js Component

App.js uses React Router to navigate between components.

  • path “/” is mapped with Home component
  • path “/customers” is mapped with CustomerList component
  • path “customers/:id” is mapped with CustomerEdit component
import React, { Component } from 'react';
import './App.css';
import Home from './Home';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import CustomerList from './CustomerList';
import CustomerEdit from './CustomerEdit';

class App extends Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route path='/' exact={true} component={Home}/>
          <Route path='/customers' exact={true} component={CustomerList}/>
          <Route path='/customers/:key' component={CustomerEdit}/>
        </Switch>
      </Router>
    )
  }
}

export default App;

Testing

– Start Reactjs Application by cmd: yarn start.

Project Goal Home Page
Project Goal Home Page

Testcase 1: Reactjs Post data to Firebase Realtime database

Project Goal Reactjs Add a Customer to Realtime Database of Firebase
Project Goal Reactjs Add a Customer to Realtime Database of Firebase
Firebase realtime datatbase - after adding customer
Firebase realtime datatbase – after adding customer

Testcase 2: Reactjs Get all data from Firebase Realtime database

Reactjs show list customers after doing CRUD operations
Reactjs show list customers after doing CRUD operations

Testcase 3: Reactjs Put data to Firebase Realtime database

Project Goal Reactjs Update Customer to Firebase
Project Goal Reactjs Update Customer to Firebase
Firebase realtime datatbase - update customer
Firebase realtime datatbase – update customer

Testcase 4: Reactjs Delete data from Firebase Realtime database

Firebase realtime datatbase - after deleting a customer
Firebase realtime datatbase – after deleting a customer
Reactjs show list customers after doing CRUD operations
Reactjs show list customers after doing CRUD operations

Sourcecode

reactjs-firebase-realtime-database

– Github:

Reactjs CRUD Firebase- github

14 thoughts on “Reactjs CRUD Firebase Realtime Database Example”

  1. I’m extremely pleased to discover this website. I wanted to thank you for ones time just for this fantastic read!! I absolutely enjoyed every part of it and i also have you bookmarked to see new stuff in your site.

Leave a Reply

Your email address will not be published. Required fields are marked *