앞서 생성한 firebaseExample 프로젝트에 간단한 게시판 기능을 구현하며 기초적인 Firebase(Realtime Database) 사용법을 정리한다.

Node.js를 이용하여 Firebase의 Realtime Database에 데이터를 저장하고 조회하는 CRUD 게시판을 제작한다.

관련된 상세한 설명은 Firebase에 정리되어 있고, 여기서는 이용하는 코드만 정리한다.

관련 소스는 GitHub에서 받을 수 있다.


1. 시작하기

2. Realtime Database 기반 게시판

3. Cloud Firestore (beta) 기반 게시판

4. 로그인 (authentication) 기능 추가

     5. 무료 호스팅(Firebase Hosting)으로 배포 I, II


앞서의 간단한 예제에서는 Firebase 라이브러리를 자바스크립트로 가져와서 사용한 예제로 별도의 설치가 없었지만,

Node.js에서 사용하기 위해서는 Firebase를 설치해야 한다.

firebaseExample 폴더에서 다음 명령어를 실행하여 Firebase를 설치한다.

npm install firebase --save


다음으로 app.js 파일을 열어서 다음 문장을 추가한다.

app.use('/board1', require('./routes/board1'));

routes 폴더에 있는 board1.js 파일을 board1 이라는 가상 폴더(/)로 사용하겠다는 것이다.

웹에서 board1/list, board1/form 과 같이 입력해서 사용한다.


board1.js의 내용은 다음과 같다.

board1.js

먼저, 콘솔에서 다음 명령어로 dateformat 라이브러리를 설치한다.

dateformat은 위 코드에서 저장된 날짜를 형식에 맞추어 출력하기 위해 사용되었다 [라인 4, 27, 39].

    npm install dateformat --save

저장 할때는 자바스크립트의 now()함수로 년월일시분초(ms)까지 저장하고,

웹 페이지에 출력할때에는 dateformat을 이용하여 년월일만 출력한다 [라인 27, 39].


Firebase의 Realtime Database를 이용하여 게시판을 만들기 위해,

앞서 테스트로 입력한 것처럼 Firebase에서 복사해온 config  값들을 붙여넣기한 후 초기화 한다 [라인 10~18].


본격적인 게시판과 관련된 코드로

데이터 CRUD(Create, Read, Update, Delete)를 구현하기 위해

boardList [라인 20], boardRead [라인 33], boardForm[라인 43], boardSave[라인 57], boardDelete[라인 73]의 5 개의 컨트롤(URL)을 정의하였다.

게시판 구성에 대한 것은 이전에 정리하여 여기서 따로 정리하지 않는다.


boardList는 글 리스트를 출력하는 컨트롤로 Realtime Database에 저장된 데이터를 가져와서 화면에 출력한다.

Realtime Database에 접근하기 위해 firebase.database()를 사용하고 [라인 21],

Realtime Database에서 board의 데이터를 모두 가져오도록(once) 했다[라인 21].

가지고 온 데이터는 키(key)와 데이터로 구성된 변수 snapshot으로 반환되는 데,

snapshot을 그대로 HTML (ejs)로 보낼 수 없어 배열 rows로 변환해서 사용한다.


별도의 변환 함수가 있는 것이 아니고,

snapshot의 개수 만큼 반복해서(forEach) [라인 23]

키는 제외하고 데이터만 추출해서(val()) [라인 24], rows에 추가한다 [라인 27].

변환이 완료되면, views의 board1폴더에 있는 boardList.ejs에 rows를 파라미터로 지정해서 호출한다 [라인 29].


게시판 리스트 구현에서 Realtime Database의 단점을 확인 할 수 있다.

orderByKey는 정렬을 의미하는데 [라인 21] 내림차순(DESC)이 제공되지 않는다.

즉, 최신글이 가장 앞에 나오는 기능을 구현할 수 없다.

검색 기능도 제한적이라 페이징 등의 처리를 구현하기 어려운 문제가 있다.

리스트와 관련된 상세한 내용은 Firebase 문서를 참고 하면 된다.


호출된 boardList.ejs [라인 29] 에서는 다음과 같이 작성되어 있다.

boardList.ejs

대부분 화면 출력을 위한 HTML 코드이고

라인 27 부터 36 이 컨트롤에서 넘겨진 데이터(rows)의 값을 적절하게 디자인해서 출력하는 코드이다.

rows 가 배열이니 배열의 개수 만큼 반복해서(for) [라인 27],

각각의 필드(brdno, brdtitle, brdwriter, brddate) 값을 화면에 출력(=)한다 [라인 30~33].


Node.js를 재가동하고(npm start), 웹 브라우저에서 http://localhost:3000/board1/boardList를 입력하여

앞서 테스트로 입력한 데이터가 그림과 같이 출력되는지 확인한다.


다음으로 글쓰기 기능을 구현한다.

글쓰기는 사용자가 입력하는 화면(boardForm)과

사용자가 저장 버튼을 눌렀을 때, 입력한 값을 받아서 저장(boardSave)하는 부분으로 구성된다.


board1.js의 코드를 보면 사용자가 입력하는 화면에서는 두 가지 기능을 처리한다.

글번호(brdno) 값이 없으면 신규(new) 글쓰기로 별 다른 처리 없이 진행하고 [라인 44~47],

값이 있으면 글 수정을 위해 글번호에 해당하는 데이터를 가지고 와서 화면에 출력한다 [라인 49~54].

신규일 경우에는[라인 44] boardForm.ejs 파일을 호출하고 끝나지만 [라인 45].

수정일 경우에는 firebase.database()에서 파라미터로 지정된 글번호(req.query.brdno)를 지정해서 하나의 값만 가지고 온다 [라인 49].

데이터를 가지고 오는 것이 글 리스트의 사용법과 동일하지만 [라인 21],

Board 뒤에 키 값을 넣어서 하나의 데이터만 가지고 오도록 하는 차이가 있다.


boardForm.ejs는 컨트롤에서 넘겨준 값(row)를 화면에 출력하는 기능을 한다.

boardForm.ejs

사용자가 새 글을 쓰는 경우에는 단순하게 HTML을 출력하고,

수정일 경우에는 넘겨 받은 값(row)를 출력하기 위해 각각의 필드 값을 지정한다 [라인 17, 21, 25].

신규인지 수정인지를 판단하기 위해 글 번호(고유값, PK) 값을 보관하는데 [라인 30],

작성일자(brddate)도 hidden 필드로 값을 보관해야 한다 [라인 31].

이것도 Realtime Database의 단점으로,

Realtime Database는 수정하는 필드 값만 지정해서 사용할 수 없다.

저장시 지정된 필드(Json 키)만 저장하기 때문에 수정시 JSon 구성에 필드 지정이 안되어 있으면 저장되지 않는다.

글 수정시 작성자, 글제목, 글내용만 수정했다고 이것만 저장하면 작성일자는 삭제된다는 의미이다.

이 예제는 필드가 몇개 없어서 hidden으로 추가하면 되지만, 실제 사용중에는 몇 십개의 필드를 사용하는 경우가 많다.

이 경우 일반적인 RDBMS처럼 구현할 수 없고, Realtime Databas는 다른 방법을 사용해야 한다.


글을 작성하고 저장 버튼을 누르면 board1.js의 boardSave 컨트롤이 호출된다 [라인 57~71].

boardSave에서는 사용자가 작성한 값을 저장(set)한다 [라인 65].

저장하기 전에, 글번호(brdno) 값이 없으면 새 글 작성으로 보고 키 값 [라인 60]과 작성일자 [라인 61]의 값을 생성한다.

글 수정일 때는 입력화면에서 받은 값을 그대로 저장하면 되는데,

HTML에서 작성일자 값이 문자로 넘어오기 때문에 다시 숫자로 변환하는 처리를 해준다 [라인 63].

Realtime Database에 저장하기 위해서는 데이터가 Json 형태로 저장되어야 하는데,

Node.js(express)에서 사용자가 입력한 값을 Json으로 넘겨 주기 때문에, 그대로(postData = req.body) 사용한다 [라인 58].


앞서의 테스트에서는 update를 사용했지만 [라인 66~68], 글 저장에서는 set을 사용하였다 [라인 65].

Update는 여러 개의 Json 데이터를 한번에 저장할 때 사용하고,

Set은 한번에 하나의 데이터를 저장할 때 사용한다.

자세한 사용법은 Firebase 문서에 정리되어 있다.


저장된 데이터는 글 리스트와 Firebase 콘솔에서 확인 할 수 있다.



글 읽기(boardRead)는 글 리스트에서 하나의 행(글번호)을 선택하면 상세한 내용을 출력하는 페이지이다 [라인 33~41].

지정된 글번호(brdno)을 가지고 오는 것은 글 수정과 동일하고 [라인 49~54], 화면에 출력하는 방법은 다음과 같다.

boardRead.ejs

boardRead.ejs의 내용은 글 수정과 비슷하게 작성하는데

글 수정은 사용자가 수정할 수 있도록 입력상자(text)를 사용하고, 글 읽기는 단순하게 지정된 값을 화면에 출력한다 [라인 16, 20, 24].


마지막으로 글삭제(boardDelete)는 주어진 글번호(brdno) 값을 remove()함수로 삭제한다 [라인 74].

글 삭제는 별도의 화면이 없고, 삭제 후 글 리스트로 이동한다 [라인 75].


이상으로 Realtime Database을 이용하여 Node.js(Express)에서 간단한 게시판 기능을 구현하였다.

제법 그럴 듯 해 보이지만, 단순한 기능 구현에도 두 가지 문제가 나타났다.

1. 내림차순 정렬 안됨

2. 데이터 수정시 모든 필드를 나열해야 함

정리하지 않았지만 이외에도 많은 단점이 보였다.


개인적으로는 Realtime Database는 단순한 정보를 저장하는 기능에 적합한 것 같고, 복잡한 데이터 처리에는 맞지 않는 것 같다.

다만, 이러한 문제들을 해결하기 위해 Cloud Firestore(베타)가 새로 나온 것 같다.






+ Recent posts