원본: 내 네이버 블로그, 2020-05-29 포스팅
오늘은 본격적으로 백엔드 기능을 구현하기에 앞서, 웹페이지에서 가장 기본적으로 CRUD API를 firebase로 구현해 볼 것이다. 전에 포스팅 관련 페이지에 들어가는 CRUD API를 firebase로 몇 번 짜 본 적이 있어서 포스팅 페이지를 기준으로 한다.
사용될 firebase 메서드는 크게 .set(), .get(), .update(), .remove() 이다.
Create : 포스팅 등록(set)
/**
* @function
* 관리자가 공지글 등록
* */
const firebase = require('firebase/app');
require('firebase/database');
require('firebase/auth');
const auth = require('../auth');
module.exports = async(title, body, imageUrl, url) => {
try{
if (!(await auth.isLogin())) {
throw new Error('PERMISSION_DENIED');
}
let noticeRef = firebase.database().ref('notice').push();
let addedTime = new Date().getTime();
await noticeRef.set({
title: title,
body: body,
imageUrl: imageUrl,
url: url,
addedTime: addedTime
});
return;
}
catch(e){
throw e;
}
}
기본적으로 firebase에서 database에 최초 등록할 때는 .set()을 사용한다.
database.ref('example')을 사용하여 데이터를 등록할 root node를 설정할 수 있다.
.push()를 사용할 경우에는 firebase 난수로 key가 생성되고, 해당 key의 하위 노드로 데이터가 set된다.
참고로 isLogin()은 로그인 상태 확인을 위해 firebase onAuthStateChange 메서드를 사용해서 짠 함수이다.
즉, 위의 경우에는
noticeRef : 데이터를 db의 'notice'루트에 저장할 거야. 이 때 키는 난수야.
noticeRef.set() : notice 루트에 이 데이터들을 저장할거야.
title(저장되는 데이터 이름) : title(parameter로 전달받는 저장될 데이터 내용)
의 구성이다.
그러면 이처럼 지정한 루트(여기서는 post이다.)에 난수가 key로 생성되고, 이 key의 하위 노드들인 contents, createdTime, rcreatedTime, uid가 실제 저장한 data이다.
Read : 포스팅 글 조회(get)
/**
* @function
* 공지글 리스트 가져오기
*/
const firebase = require('firebase/app');
require('firebase/database');
const auth = require('../auth');
module.exports = async (key) => {
try {
if (!(await auth.isLogin())) {
throw new Error('PERMISSION_DENIED');
}
if (!key) {
return await allNotices();
}
return await thatNotice(key);
}
catch (e) {
throw e;
}
}
let thatNotice = async function(key){
let ref = (await firebase.database().ref('notice/').orderByChild('key').equalTo(key).once('value')).val();
if (!ref) {
throw new Error('database/no-matched');
}
return ref;
}
let allNotices = async function() {
let ref = (await firebase.database().ref('notice').once('value')).val();
return ref;
}
조회는 firebase의 .get()을 사용한다고 하는데, 사실상 써본적이 거의 없는 것 같다.
대신 지금처럼 orderByChild와 equalTo를 사용하여 특정 데이터 로드하는 방법을 훨씬 많이 썼다.
해당 코드는 관리자용 백엔드 코드이기 때문에, 전체 글을 로드하는 함수와 해당 글을 로드하는 함수를 따로 만들었다. 이 외에도 최근 5개 포스팅만 로드는 orderByChild().equalTo().limitToLost(5)와 같은 방법으로 가능하다.
Update : 포스팅 수정(update)
/**
* @function
* 관리자가 공지글 업데이트. 업데이트 하는 부분은 제목/타입/내용/url
* @param
* key : 공지글 삭제 시 해당 공지글의 db key를 이용하여 업데이트
* filed : 업데이트 할 부분
* contents : 업데이트 할 내용.
*/
const firebase = require('firebase/app');
require('firebase/database');
const auth = require('../auth');
module.exports = async (key, filed, contents) => {
try {
if (!(await auth.isLogin())) {
throw new Error('PERMISSION_DENIED');
}
//key를 가지고 db쿼리
let ref = firebase.database().ref('notice/' + key);
//db에 key에 해당하는 내용이 있을 때
if ((await ref.once('value')).val()) {
switch (filed) {
case 'title':
await ref.update({ title: contents });
return
case 'body':
await ref.update({ body: contents });
return
case 'imageUrl':
await ref.update({ imageUrl: contents });
return
case 'url':
await ref.update({ url: contents });
return
default:
throw new Error('common/invalid-params');
}
}
else { //db에 해당 key가 없을 경우
throw new Error('database/no-matched');
}
}
catch (e) {
throw e;
}
}
update는 주의를 좀 기울여야 한다.
firebase의 update 메서드를 사용할 때 key를 잘못 잡으면 데이터가 업데이트 되는 것이 아니라 해당 자리에 새로운 key가 생기고 그 key의 하위값으로 업데이트한 내용이 들어가기 때문.
Delete : 포스팅 삭제(remove)
/**
* @function
* 관리자가 공지글 삭제 시 db에는 expired가 true로 업데이트 됨.
* @param
* key : 공지글 삭제 시 해당 공지글의 db key를 이용하여 삭제.
*/
const firebase = require('firebase/app');
require('firebase/database');
const auth = require('../auth');
module.exports = async (key) => {
try {
if (!(await auth.isLogin())) {
throw new Error('PERMISSION_DENIED');
}
let ref = firebase.database().ref('notice/' + key);
//db에 해당 key가 있을 경우
if ((await ref.once('value')).val()) {
await ref.remove();
}
else { //db에 해당 key가 없을 경우
throw new Error('database/no-matched');
}
}
catch (e) {
throw e;
}
}
remove() 메서드를 사용하며 key를 받아와서 해당 key와 일치하는 key의 데이터를 통째로 지운다.
이제 해당 모듈들을 적절한 이름으로 exports시켜서 index.js에서 프론트에서 사용될 API 로직을 짠 다음 프론트엔드 구성만 하면 된다.
끄읏~
'Web' 카테고리의 다른 글
[AWS]AWS-EC2 인스턴스에 Express 배포 (0) | 2020.09.22 |
---|---|
[Firebase]Firebase 작업환경 세팅 (0) | 2020.08.06 |
[JavaScript]자바스크립트로 중복없는 쿠폰번호 생성(4)_프론트엔드 입력 파라미터 (0) | 2020.08.06 |
[Jest]jest 테스팅 프레임워크를 사용한 테스팅 환경 세팅 및 오류 해결 (0) | 2020.08.06 |
[PDFTron]Cmake와 Swig를 이용한 파이썬 개발환경 세팅 (0) | 2020.08.06 |
댓글