일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- peerdependencies
- 제너레이터와 async/await
- var 사용금지
- 비전공이지만 개발자로 먹고삽니다
- 디스트럭처링
- Property Attribute
- const
- 자바스크립트 딥다이브
- 브라우저의 렌더링 과정
- 스코프
- DOM
- 커리어
- Set과 Map
- 모던 자바스크립트 Deep Dive
- Babel과 Webpack
- 이미지 갤러리 최적화
- 블로그 서비스 최적화
- 올림픽 통계 서비스 최적화
- 딥다이브
- 자바스크립트 패턴
- ES6함수 추가기능
- 이벤트
- 빌트인 객체
- 전역변수의문제점
- package management
- 자바스크립트
- 프론트엔드 성능 최적화 가이드
- 인터넷 장비
- 프로퍼티 어트리뷰트
- 프로그래머스
- Today
- Total
Dev Blog
How to use Real-time DB of Firebase 본문
How to use Real-time DB of Firebase
Nomad Kim 2021. 4. 20. 00:49- 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
'Web Development > General Tech Knowledges' 카테고리의 다른 글
배경이미지 브라우저에 꽉 채우기 (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 |