How to use Real-time DB of Firebase

2021. 4. 20. 00:49·Computer Science/Terminology and Concepts
  • How to do initial setting
  • Structure of Database
  • How to make CRUD function
  • Efficient State management
  • How to make table

 

How to do initial setting(how to find database)

Creates and initializes a Firebase app instance.

 

firebase.js

import firebase from "firebase/app";
import "firebase/database";
import dotenv from "dotenv";
dotenv.config();

var firebaseConfig = {
  apiKey: process.env.REACT_APP_APIKEY,
  authDomain: process.env.REACT_APP_AUTHDOMAIN,
  databaseURL: process.env.REACT_APP_DATABASEURL,
  projectId: process.env.REACT_APP_PROJECTID,
  storageBucket: process.env.REACT_APP_STORAGEBUCKET,
  messagingSenderId: process.env.REACT_APP_MSGSENDERID,
  appId: process.env.REACT_APP_APPID,
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);

let realTimeDB = firebase.database().ref(); //how to find real-time db location
export default realTimeDB;

firebase.database.Reference

: A Reference represents a specific location in your Database and can be used for reading or writing data to that Database location.

 

Comparison with the case of Cloud Firestore / Storage

import firebase from "firebase/app";
import "firebase/storage"; //store images
import "firebase/firestore"; //Cloud firestore
import "firebase/auth";
import dotenv from "dotenv";
dotenv.config();
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
var firebaseConfig = {
  apiKey: process.env.REACT_APP_APIKEY,
  authDomain: process.env.REACT_APP_AUTHDOMAIN,
  projectId: process.env.REACT_APP_PROJECTID,
  storageBucket: process.env.REACT_APP_STORAGEBUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGESENDER,
  appId: process.env.REACT_APP_APPID,
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);

const projectStorage = firebase.storage(); //This reference points to the root of Cloud Storage bucket.
const projectFirestore = firebase.firestore();
const timeStamp = firebase.firestore.FieldValue.serverTimestamp;
const projectAuth = firebase.auth();

export { projectStorage, projectFirestore, timeStamp, projectAuth };

Structure of Database

1) Realtime Database

Stores data as one large JSON tree.

  • Simple data is very easy to store.
  • Complex, hierarchical data is harder to organize at scale.

 

2) Cloud Firestore

Stores data as collections of documents.

  • Simple data is easy to store in documents, which are very similar to JSON.
  • Complex, hierarchical data is easier to organize at scale, using subcollections within documents.
  • Requires less denormalization and data flattening.

 

Common Sense

 

  • Both Realtime Database and Cloud Firestore are NoSQL Databases.
  • Client-first SDKs, with no servers to deploy and maintain
  • Realtime updates
  • Free tier, then pay for what you use

Other Differences

  Realtime DB

Cloud Firestore

Offline support iOS and Android clients

iOS, Android, and web clients

Presence(User) supported

Not supported natively

Querying Deep queries with limited sorting and filtering functionality

Indexed queries with compound sorting and filtering

Writes and transactions Basic write and transaction operations

Advanced write and transaction operations

Reliability and performance a regional solution

a regional and multi-region solution that scales automatically

Scalability Scaling requires *sharding

Scaling is automatic

Security Cascading rules language that separates authorization and validation

Non-cascading rules that combine authorization and validation

*Sharding: a database architecture pattern related to horizontal partitioning — the practice of separating one table’s rows into multiple different tables, known as partitions.

For more detail: nesoy.github.io/articles/2018-05/Database-Shard

 

source from: firebase.google.com/docs/firestore/rtdb-vs-firestore?hl=en


How to make CRUD function

C.R.U.D.

 

1. Create / Update

"addOrEdit" method

1) Get input info from ContactForm.js when submit button clicked

2-1) If Edit button is not clicked, push new info to database

2-2) If Edit button is clicked, set new info to the element accordingly by using currenId

 

2. Read

"useEffect" method

Snapshot database

 

3. Delete

"handleDelete" method

Delete selected data by using currenId

 

Contacts.js

function Contacts() {
  const [contactObjs, setContactObjs] = useState({})
  const [currentId, setCurrentId] = useState("")

  const addOrEdit = obj =>{
    if(currentId === ""){
      realTimeDB.child('contacts').push(
        obj,
        err => {
          if(err) {
            console.log(err)
          } else {
            setCurrentId('')
            }
        })
    } else {
      realTimeDB.child(`contacts/${currentId}`).set(
        obj,
        err => {
          if(err) {
            console.log(err)
            } else {
              setCurrentId('')
            }
        })
    }
  }
  const handleDelete = (currentId) => {
    if(window.confirm('Are you sure to delete this record?')){
      realTimeDB.child(`contacts/${currentId}`).remove(
        err => {
          if(err) {
            console.log(err)
          } else {
            setCurrentId('')
            }
        })
    }
  }

  useEffect(() => {
    realTimeDB.child('contacts').on('value', snapshot => {
      if(snapshot.val() != null) {
        setContactObjs({
          ...snapshot.val()
        })
      } else {
        setContactObjs({})
      }
    })
  },[])

  return (
    ...
    ContactForm {...({ addOrEdit, currentId, contactObjs})}/>
    ... 
      <tbody>
            {
              Object.keys(contactObjs).map(id=>{ 
                //객체 그룹일 때 Object.keys 를 이용하여 배열화 시킬 수 있는데,
                //map 의 각 요소는 id(데이터베이스에서 임의로 만든 id값) 이다.  
                return (                
                <tr key={id}>
                  <td>{contactObjs[id].fullName}</td>
                  <td>{contactObjs[id].mobile}</td>
                  <td>{contactObjs[id].email}</td>
                  <td>
                    <div className="btn text-primary" onClick={() => setCurrentId(id)}>
                      <i className="fas fa-pencil-alt"></i>
                    </div>
                    <div className="btn text-danger" onClick={() => handleDelete(id)}>
                      <i className="fas fa-trash-alt"></i>
                    </div>
                  </td>
                </tr>)
              })
            }
          </tbody>
  )
}

export default Contacts;

ContactForm.js

import React, {useState, useEffect} from "react";

function ContactForm( { addOrEdit, currentId, contactObjs} ) {
  const initialFieldValues = {
    fullName:"",
    mobile:"",
    email:"",
    address:""
  }

  const[values, setValues] = useState(initialFieldValues);
  const handleInputChange = e =>{
    const { name, value } = e.target;
    setValues({...values, [name]: value})
  }
  
  const handleFormSubmit = (e) => {
    e.preventDefault();
    addOrEdit(values);
  }
  //edit 을 클릭하면 id 값이 전달된다.
  useEffect(()=>{
    if(currentId === ""){
      setValues({...initialFieldValues})
    } else {
      setValues({...contactObjs[currentId]})
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  },[currentId, contactObjs])

  return (
    <form action="" autoComplete="off" onSubmit={handleFormSubmit}>
      <div>
        <div className="form-group input-group">
          ...
          <input className="form-control" placeholder="Full Name" name="fullName" value={values.fullName} onChange={handleInputChange}/>
        </div>
        <div className="form-group input-group">
          ...
          <input className="form-control" placeholder="Mobile Number" name="mobile" value={values.mobile} onChange={handleInputChange}/>
        </div>
        <div className="form-group input-group">
          ...
          <input className="form-control" placeholder="E-mail" name="email" value={values.email} onChange={handleInputChange}/>
        </div>
        <div className="form-group input-group">
          ...
          <input className="form-control" placeholder="Address" name="address" value={values.address} onChange={handleInputChange}/>
        </div>
      </div>
      <div className="form-group submit">
        <input type="submit" value={currentId === "" ? "Save":"Update"} className="btn btn-primary btn-block"/>
      </div>
    </form>
    )
}

export default ContactForm;

Efficient State management

Utilize name / value props to update values(fullName, mobile, email, address) easily.

import React, {useState, useEffect} from "react";

function ContactForm( { addOrEdit, currentId, contactObjs} ) {
  const initialFieldValues = {
    fullName:"",
    mobile:"",
    email:"",
    address:""
  }

  const[values, setValues] = useState(initialFieldValues);
  //here is the point!
  const handleInputChange = e =>{
    const { name, value } = e.target;
    setValues({...values, [name]: value})
  }
  
...

  return (
    <form action="" autoComplete="off" onSubmit={handleFormSubmit}>
      <div>
        <div className="form-group input-group">
          ...
          <input className="form-control" placeholder="Full Name" name="fullName" value={values.fullName} onChange={handleInputChange}/>
        </div>
        ...
    </form>
    )
}

export default ContactForm;

How to make table

Concept

<table>
    <thead> : defines a set of rows defining the head of the columns of the table.
        <tr> : Table Row Element (<tr>) defines a row of cells in a table
            <th>menu</th> : defines a cell as header of a group of table cells
            <th>price</th>
        </tr>
    </thead>
    <tbody> :  encapsulates a set of table rows that comprises the body of the table 
        <tr>
            <td>steak</td>
            <td>45000</td>
        </tr>
        <tr>
            <td>wine</td>
            <td>45000</td>
        </tr>
    </tbody>
    <tfoot> : Its value will be null if there is no such element.
        <tr>
            <td>Total</td>
            <td>103000</td>
        </tr>
    </tfoot>
</table>

 

 <table className="table table-borderless table-stripped">
          <thead className="thead-light">
            <tr>
              <th>Full Name</th>
              <th>Mobile</th>
              <th>Email</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            {
              Object.keys(contactObjs).map(id=>{ 
                return (                
                <tr key={id}>
                  <td>{contactObjs[id].fullName}</td>
                  <td>{contactObjs[id].mobile}</td>
                  <td>{contactObjs[id].email}</td>
                  <td>
                    <div className="btn text-primary" onClick={() => setCurrentId(id)}>
                      <i className="fas fa-pencil-alt"></i>
                    </div>
                    <div className="btn text-danger" onClick={() => handleDelete(id)}>
                      <i className="fas fa-trash-alt"></i>
                    </div>
                  </td>
                </tr>)
              })
            }
          </tbody>
</table>

 

 

 

Learn from:

youtu.be/pI4438IHBYY

'Computer Science > Terminology and Concepts' 카테고리의 다른 글

배경이미지 브라우저에 꽉 채우기  (0) 2021.05.21
How to improve an E-Commerce Checkout Experience: UI/UX Case study  (0) 2021.05.11
React Convenient Tools - Prettier, ESLint, Snippet  (0) 2021.04.19
How to Set up S3 bucket  (0) 2021.04.11
프론트엔드 필수 반응형 CSS 단위 정리  (0) 2021.04.08
'Computer Science/Terminology and Concepts' 카테고리의 다른 글
  • 배경이미지 브라우저에 꽉 채우기
  • How to improve an E-Commerce Checkout Experience: UI/UX Case study
  • React Convenient Tools - Prettier, ESLint, Snippet
  • How to Set up S3 bucket
JTB
JTB
웹/앱 개발 정보를 공유하고 있습니다.
  • JTB
    JTechBlog
    JTB
  • 전체
    오늘
    어제
    • All About Programming;) N
      • Computer Science
        • Terminology and Concepts
        • Network
        • Operating System
        • Database
        • Data Structure
      • Frontend
        • Javascript Essentials
        • Perfomance Optimization
        • JS Patterns
        • Next.js
        • Flutter
      • Backend
        • Node.js
      • DevOps
        • Docker & Kubernetes
      • Coding Test N
        • LeetCode N
        • Programmers
      • Tech Books & Lectures
        • Javascript_Modern JS Deep d..
        • Network_IT 엔지니어를 위한 네트워크 입문
      • Projects
        • PolyLingo_2025
        • Build Your Body_2024
        • JStargram_2021
        • Covid19 Tracker_2021
        • JPortfolio_2021
      • BootCamp_Codestates
        • TIL
        • TILookCloser
        • Pre Tech Blog
        • IM Tech Blog
        • Daily Issues and DeBugging
        • First Project
        • Final Project
        • Sprint Review
        • Good to Know
        • Socrative Review
        • HTML &amp; CSS
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 글쓰기
    • 관리
  • 공지사항

  • 인기 글

  • 태그

    leetcode
    이벤트
    CPU scheduling algorithm
    JavaScript
    Network
    TCP/IP
    Time complexity and Space complexity
    커리어
    스코프
    need a database
    indie hacker
    Shared resources
    자바스크립트 딥다이브
    structure of os
    Operating System
    testing
    Threads and Multithreading
    모던 자바스크립트 Deep Dive
    Binary Tree BFS
    mobile app
    Data Structure
    How memory manage data
    DOM
    VoiceJournal
    자바스크립트
    polylingo
    js pattern
    딥다이브
    database
    프론트엔드 성능 최적화 가이드
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
JTB
How to use Real-time DB of Firebase
상단으로

티스토리툴바