Firebase 에서 사용할 수 있는 DB 종류
2개가 존재하며 둘다 NoSQL DB이며 실시간으로 데이터가 동기화된다.
자세한 차이점은 데이터베이스 선택: Cloud Firestore 또는 실시간 데이터베이스 에 적혀있다.
Database 설정
1. 개발 에서 [Database] 를 선택
2. [데이터베이스 만들기] 클릭
3. 프로덕션 모드에서 시작
4. Cloud Firestore 위치를 asia-east2 로 설정
asia-east2(홍콩) 이며 Firebase 실시간 데이터베이스(Realtime Database) 은 적용되지 않는다. 위치에 대한 자세한 설명
5. 데이터베이스가 다 만들어졌다.
RealTimeDatabase 사용
Firebase Admin Realtime Database API 소개
Realtime Database 설정
1. Database 옆 항목에서 [Realtime Database] 를 선택한다.
2. [규칙] 을 선택한 후 규칙을 변경한다.
false -> true 로 수정한다.
DB에 데이터를 넣고 데이터를 불러오는 알아보자.
일단, 데이터를 게시판 형태로 DB를 이용해보자.
app.js
const postsRouter = require('./routes/posts');
app.use('/posts', postsRouter);
// false 를 true 로 수정
app.use(express.urlencoded({ extended: true }));
express.urlencoded 관련 설명 : https://sjh836.tistory.com/154
routes/rPosts.js
var express = require('express');
var router = express.Router();
const admin = require('firebase-admin');
// firebase Admin 초기화
const firebaseAdmin = admin.initializeApp({
credential: admin.credential.cert({
"firebaseAdmin Key"
}),
databaseURL: "",
storageBucket: ""
}, "posts");
const dateFormat = require('dateformat');
///
/// 데이터 베이스 관련
///
router.get('/List', function(req, res, next) {
firebaseAdmin.database().ref('posts').orderByKey().once('value', function(snapshot) {
var rows = [];
snapshot.forEach(function(childSnapshot) {
var childData = childSnapshot.val();
childData.postsdate = dateFormat(childData.postsdate, "yyyy-mm-dd");
rows.push(childData);
});
res.render('rPosts/List', {rows: rows});
});
});
router.get('/Read', function(req, res, next) {
firebaseAdmin.database().ref('posts/' + req.query.postsno).once('value', function(snapshot) {
var childData = snapshot.val();
childData.postsno = snapshot.key;
childData.postsdate = dateFormat(childData.postsdate, "yyyy-mm-dd");
res.render('rPosts/Read', {row:childData});
});
});
router.get('/Write', function(req, res, next) {
if(!req.query.postsno) {
res.render('rPosts/Write', {row:""});
return;
}
firebaseAdmin.database().ref('posts/'+req.query.postsno).once('value', function(snapshot) {
var childData = snapshot.val();
childData.postsno = snapshot.key;
res.render('rPosts/Write', {row: childData});
});
});
router.post('/Save', function(req, res, next) {
var postData = req.body;
if (!postData.postsno) {
postData.postsno = firebaseAdmin.database().ref().child('posts').push().key;
postData.postsdate = Date.now();
} else {
postData.postsdate = Number(postData.postsdate);
}
firebaseAdmin.database().ref('posts/' + req.body.postsno).set(
req.body, function(err) {
if(err) {
console.log(err);
} else {
console.log(req.body.postsno + " Upload successfully");
}
});
res.redirect('List');
});
router.get('/Delete', function(req, res, next) {
firebaseAdmin.database().ref('posts/' + req.query.postsno).remove();
res.redirect('List');
});
module.exports = router;
const admin = require('firebase-admin');
// firebase Admin 초기화
const firebaseAdmin = admin.initializeApp({
credential: admin.credential.cert({
"firebaseAdmin Key"
}),
databaseURL: "",
storageBucket: ""
}, "posts");
애플리케이션에서 여러 프로젝트를 사용할일이 있다면 애플리케이션에서 여러 프로젝트 사용 을 참고하여 각 admin.initializeApp 에 이름(Ex - "posts")을 부여 해줘야한다. 하나의 프로젝트에서만 사용할 경우 이름을 부여하지 않아도 된다.
// posts 의 데이터를 모두(once) 얻어 온 데이터(snapshot)는 key, Data 로 이루어진 데이터를 받는다.
firebaseAdmin.database().ref('posts').orderByKey().once('value', function(snapshot)
// posts에서 특정 key로 데이터를 전부 받아온다.
firebaseAdmin.database().ref('posts/' + req.query.postsno).once('value', function(snapshot)
// 새로운 key를 받아온다.
postData.postsno = firebaseAdmin.database().ref().child('posts').push().key;
// posts에서 특정 key로 데이터를 입력한다. Key가 겹칠 경우 자동으로 덮어쓴다.
firebaseAdmin.database().ref('posts/' + req.body.postsno).set()
// posts에서 특정 key로 된 데이터를 삭제한다.
firebaseAdmin.database().ref('posts/' + req.query.postsno).remove();
ref, once 에 관련된 내용은 아래 링크에서 자세하게 알 수 있다.
List.ejs
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Test & MySite</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<div id="main">
<table border="1" style="width:600px">
<caption>Firebase RealTime Database Sample</caption>
<colgroup>
<col width='8%'/>
<col width='*%' />
<col width='15%'/>
<col width='15%'/>
</colgroup>
<thead>
<tr>
<th>No.</th>
<th>Title</th>
<th>Writer</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<%
for(var i=0; i<rows.length; i++) {
%>
<tr>
<td><%=rows.length - i%></td>
<td><a href='Read?postsno=<%=rows[i].postsno%>'><%=rows[i].poststitle%></a></td>
<td><%=rows[i].postswriter%></td>
<td><%=rows[i].postsdate%></td>
</tr>
<%
}
%>
</tbody>
</table>
<a href="Write">New</a>
</div>
</body>
</html>
Read.ejs
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Test & MySite</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<table border="1" style="width:600px">
<caption>Firebase RealTime Database Sample</caption>
<colgroup>
<col width='15%'/>
<col width='*%'/>
</colgroup>
<tbdoy>
<tr>
<td>Writer</td>
<td><%=row.postswriter%></td>
</tr>
<tr>
<td>Title</td>
<td><%=row.poststitle%></td>
</tr>
<tr>
<td>Memo</td>
<td><%=row.postsmemo%></td>
</tr>
</tbdoy>
</table>
<a href="#" onclick="history.back(-1)">글 목록</a>
<a href="Delete?postsno=<%=row.postsno%>">삭제</a>
<a href="Write?postsno=<%=row.postsno%>">수정</a>
</body>
</html>
Write.ejs
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Test & MySite</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<form name="form1" action="Save" method="POST">
<table border="1" style="width:600px">
<caption>Firebase RealTime Database Sample</caption>
<colgroup>
<col width='15%'/>
<col width='*%'/>
</colgroup>
<tbdoy>
<tr>
<td>Writer</td>
<td><input type="text" name="postswriter" size="20" maxlength="20" value="<%=row.postswriter%>"></td>
</tr>
<tr>
<td>Title</td>
<td><input type="text" name="poststitle" size="70" maxlength="250" value="<%=row.poststitle%>"></td>
</tr>
<tr>
<td>Memo</td>
<td><textarea name="postsmemo" rows="5" cols="60"><%=row.postsmemo%></textarea></td>
</tr>
</tbdoy>
</table>
<a href="#" onclick="form1.submit()">저장</a>
<input type="hidden" name="postsno" value="<%=row.postsno%>">
<input type="hidden" name="postsdate" value="<%=row.postsdate%>">
</form>
</body>
</html>
서버를 실행한 후 http://localhost:3000/rPosts/List 에 접속하여 [New] 버튼을 눌러 새로운 글을 작성한다.
글을 [저장] 을 할 경우 Firebase Realtime Database 에 posts 이 새로 생기며 안에 새로운 데이터가 입력된다.
Firebase Realtime Database 단점
1. 내림차순(DESC) 정렬 안됨
2. 데이터 수정 시 모든 필드를 나열해야 함
3. 검색 기능도 제한적이다.
참고
https://forest71.tistory.com/166
Cloud Firestore 사용
Colud Firestore 설정
1. Cloud Firestore 의 [규칙] 탭에서 규칙을 수정한다. (Ex. allow read, write: if false -> allow read, write: if request.auth.uid != null;)
규칙에 대한 설명
Cloud Firestore 사용법
app.js
const cpostsRouter = require('./routes/cPosts');
app.use('/cPosts', cpostsRouter);
// false 를 true 로 수정
app.use(express.urlencoded({ extended: true }));
routes/cPosts.js
var express = require('express');
var router = express.Router();
const admin = require('firebase-admin');
// firebase Admin 초기화
const firebaseAdmin = admin.initializeApp({
credential: admin.credential.cert({
"type": ,
"project_id": ,
"private_key_id": ,
"private_key": ,
"client_email": ,
"client_id": ,
"auth_uri": ,
"token_uri": ,
"auth_provider_x509_cert_url": ,
"client_x509_cert_url":
}),
databaseURL: ,
storageBucket:
}, "cposts");
const dateFormat = require('dateformat');
///
/// 데이터 베이스 관련
///
router.get('/List', function(req, res, next) {
firebaseAdmin.firestore().collection('posts').orderBy("postsdate", "desc").get()
.then((snapshot) => {
var rows = [];
snapshot.forEach((element) => {
var childData = element.data();
childData.postsdate = dateFormat(childData.postsdate, "yyyy-mm-dd");
rows.push(childData);
});
res.render('cPosts/List', {rows:rows});
return;
}).catch((err) => {
console.log(err);
});
});
router.get('/Read', function(req, res, next) {
firebaseAdmin.firestore().collection('posts').doc(req.query.postsno).get()
.then((snapshot) => {
var childData = snapshot.data();
res.render('cPosts/Read', {row:childData});
return;
}).catch((err) => {
console.log(err);
});
});
router.get('/Write', function(req, res, next) {
if(!req.query.postsno) {
res.render('cPosts/Write', {row:""});
return;
}
firebaseAdmin.firestore().collection('posts').doc(req.body.postsno).get()
.then((snapshot) => {
var childData = snapshot.data();
res.render('cPosts/Write', {row:childData});
return;
}).catch((err) => {
console.log(err);
});
});
router.post('/Save', function(req, res, next) {
var postData = req.body;
if (!postData.postsno)
{
postData.postsdate = Date.now();
doc = firebaseAdmin.firestore().collection('posts').doc();
postData.postsno = doc.id;
doc.set(postData);
}
else {
doc = firebaseAdmin.firestore().collection('posts').doc(postData.postsno);
doc.update(postData);
}
res.redirect('List');
return;
});
router.get('/Delete', function(req, res, next) {
firebaseAdmin.firestore().collection('posts').doc(req.query.postsno).delete();
res.redirect('List');
return;
});
module.exports = router;
// 'posts' 컬렉션의 전체 데이터를 'postsdate'을 기준으로 내림차순 정렬 한 후 가지고 온다.
firebaseAdmin.firestore().collection('posts').orderBy("postsdate", "desc").get()
// 'posts' 컬렉션에서 특정 key 값(req.query.postsno) 를 가진 데이터를 가지고 온다.
firebaseAdmin.firestore().collection('posts').doc(req.query.postsno).get()
// 'posts' 컬렉션에서 새로운 key 값을 생성 후
var doc = firebaseAdmin.firestore().collection('posts').doc();
postData.postsno = doc.id;
// 새로운 데이터를 넣는다.
doc.set(postData);
// 'posts' 컬렉션에서 기존 key 값(postData.postsno)의 데이터를
doc = firebaseAdmin.firestore().collection('posts').doc(postData.postsno);
// 수정한다.
doc.update(postData);
서버를 실행한 후 http://localhost:3000/cPosts/List 에 접속하여 [New] 버튼을 눌러 새로운 글을 작성한다.
'posts' 라는 새로운 컬렉션이 생기고 새로운 key 값을 가진 데이터가 저장이 된다.
'Programming > Firebase' 카테고리의 다른 글
[Firebase] Hosting 사용하기 (0) | 2019.11.26 |
---|---|
[Firebase] Web에서 Storage 사용하기 (2) | 2019.11.20 |
[Firebase] Web에서 Email, Google 로그인 사용하기 (0) | 2019.11.18 |
[Firebase] Node.js 개발 환경 구축 (0) | 2019.11.18 |
[Firebase] 시작하기 (0) | 2019.11.18 |
최근댓글