Firebase는 Realtime Database외에 Cloud Firestore (beta)라는 클라우드 기반 데이터베이스 솔루션을 제공한다.

구글에 따르면 Cloud Firestore는 유연하고 확장 가능한 NoSQL 클라우드 데이터베이스라고 하고

두 데이터 베이스에 대한 차이는 Firebase 문서에 잘 정리되어 있다.


이번에는 앞서 생성한 예제(firebaseExample) 프로젝트의 Realtime Database를 Cloud Firestore로 변환하여 간단한 게시판 기능을 구현한다.

앞서 작성한 Realtime Database 예제에서 Realtime Database에 접속하여 사용하는 코드만

Cloud Firestore 용 코드로 수정하는 방식으로 정리하기 때문에 이전 내용을 먼저 숙지 해야 한다.

관련된 상세한 설명은 Firebase 문서를 참고하면 되고, 관련 소스는 GitHub에서 받을 수 있다.


1. 시작하기

2. Realtime Database 기반 게시판

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

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

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


Cloud Firestore (beta)를 사용하기 위해 Firebase 콘솔의 Database 관리화면에서 상단에 있는 [Realtime Database]를 선택한다.

그림과 같이 Realtime Databas와 Cloud Firestore 선택 화면이 나타난다.

(왼쪽에 있는 [Database] 메뉴를 선택해도 된다.)


Cloud Firestore를 선택하면 다음과 같이 화면이 출력된다.

실제로는 [잠금모드로 시작]을 선택해야 하지만, 편의상 [테스트 모드로 시작]을 선택한다.


Realtime Databas가 Cloud Firestore로 변경되어 출력되면 사용할 준비가 된 것이다.


하나의 앱(웹)에 하나의 Firebase의 프로젝트가 사용될 수 있기 때문에,

다음과 같이 app.js에서 board1 (Realtime Databas예제)을 주석처리하고 board2 (Cloud Firestore 예제)를 추가해 준다.

전체 코드를 보기 위해 각각의 js 파일에서 Firebase에 접속하도록 작성했기 때문에 모든 예제를 동시에 실행할 수 없다.

실제 사용할때는 하나의 데이터 베이스만 선언해서 사용하도록 구현해야 한다.


board1과 board2는 대부분 동일한 코드로 구성되었고, 데이터 베이스 관련 부분만 차이가 있다.

따라서 board1.js와 board2.js의 차이나는 부분만 정리한다.

대부분의 HTML(ejs)는 동일하기 때문에 board1 폴더를 그대로 복사해서 사용하면 된다.


먼저, board2.js의 코드는 다음과 같다.

board2.js

Realtime Databas와 Cloud Firestore의 차이는 Firebase 문서에 잘 정리되어 있다.

사용한 코드 상의 차이를 몇 개만 정리하면,

Realtime Databas는 firebase.database()로 데이터를 조작하고

Cloud Firestore는 firebase.firestore()로 조작한다 [라인 19].

board1에서는 firebase.database()을 그대로 사용했고

board2에서는 firebase.firestore()를 db 변수로 선언해서 사용한다 [라인 19].


주의: Firebase 서버에 접속하는 방법에도 차이가 있지만 여기서 정리하지 않고 Hosting에서 다시 정리한다.

Firebase에서는 Firestore 사용시 서비스 계정을 이용을 추천하는데, 시작하는 수준에서 너무 많은 내용을 다루면 복잡할 것 같아서 정리하지 않는다.


데이터를 가지고 오는 코드에도 차이가 있다.

Realtime Databas는 Json 노드 방식으로 저장을 하고,

Cloud Firestore는 컬렉션(collection)이 있고, 그 하위에 문서(Document), 그리고 Json 데이터가 필드로 저장된다.

다음 그림과 같이 board 컬렉션에 고유값으로 생성된 문서(gprx1Fq0apDB6tQFv7rb), 그리고 게시판  데이터(Json)가 저장된다.

즉 일반적인 관계형 데이터 베이스로 이야기 하면, board 테이블에 하나의 행(문서)이 Json구조로 저장되는 것이다.

데이터 행 구분을 Realtime Database와 동일하게 고유값으로 구별하여 작성하였다.


실제 구현된 코드를 보면 다음 코드와 같이 FireStore에서 조회된 데이터 처리는 동일하다.

데이터를 조회하는 함수 이름에 조금의 차이가 있다.

router.get('/boardList', function(req, res, next) {
    db.collection('board').orderBy("brddate", "desc").get()
        .then((snapshot) => {
            var rows = [];
            snapshot.forEach((doc) => {
                var childData = doc.data();
                childData.brddate = dateFormat(childData.brddate, "yyyy-mm-dd");
                rows.push(childData);
            });
            res.render('board2/boardList', {rows: rows});
        })
        .catch((err) => {
            console.log('Error getting documents', err);
        });
});

board로 콜렉션(collection)을 지정하고, once가 아닌 get을 사용한다.

가장 큰 차이는 올림차순(desc) 정렬이 가능하다는 것이다.

이외에도 다양한 조건에 의한 검색이 가능하고, 상세한 설명은 Firebase 문서에 정리되어 있다.


글 읽기(baordRead)와 글 수정(baordForm)의 데이터 조회도 리스트 코드와 동일해서 따로 정리하지 않는다.


Realtime Databas와 Cloud Firestore의 차이 중 하나는 저장 방식에 있다.

Cloud Firestore에서는 새글을 작성할때,

컬렉션을 지정하고(db.collection("board")) 문서 함수를 (db.collection("board").doc())를 호출하면,

새로운 문서가 생성되고 고유 번호(doc.id)가 자동으로 부여된다.

router.post('/boardSave', function(req,res,next){
    var postData = req.body;
    if (!postData.brdno) {  // new
        postData.brddate = Date.now();
        var doc = db.collection("board").doc();
        postData.brdno = doc.id;
        doc.set(postData);
    } else {                // update
        var doc = db.collection("board").doc(postData.brdno);
        doc.update(postData);
    }
   
    res.redirect('boardList');
});

글을 저장할때 사용하는 set과 update의 의미가 Realtime Databas와 차이가 있다.

set은 기존에 데이터가 있던 지, 없던지 새로 작성하고(있으면 삭제),

update은 기존 데이터를 수정하여 저장한다.

특히, update는 모든 필드가 지정되지 않아도 지정된 필드만 수정한다.

앞서 Realtime Databas의 글 저장 예제에서 처럼 brddate을 HTML(boardForm.ejs)에서 hidden 필드로 가지고 있을 필요가 없다.


이상으로 Cloud Firestore를 이용하여, Realtime Database와 유사하게 게시판 기능을 구현하였다.

Cloud Firestore는 검색 엔진인 루씬(Lucene)의 향기를 풍기며, 제법 강력한 데이터베이스 기능을 제공하고 있는 것 같다.

보다 상세한 기능은 문서를 읽어보길 바라고,

특히 데이터 쿼리 문서를 읽어 보면 제법 그럴듯한 게시판을 구현 할 수 있을 것 같다. (이건 각자 ~~)


주의: Node.js 6 이하의 버전에서는 다음과 같은 오류가 발생한다.

Function DocumentReference.update() called with invalid data. Data must be an object, but it was: a custom object
FirebaseError: Function DocumentReference.update() called with invalid data. Data must be an object, but it was: a custom object
    at FirestoreError.Error (native)


json 데이터 형식이 맞지 않아서 생기는 오류로 다음과 같은 변환 처리를 해줘야 한다.

router.post('/boardSave', function(req,res,next){
    var postData = JSON.parse( JSON.stringify(req.body));

    생략 ~~


콘솔창에 다음과 같은 경고 메시지도 출력된다.

Firebase 초기화후에 다음과 같이 설정하면 위 경고 메시지를 제거할 수 있다.

생략 ~~

firebase.initializeApp(config);
var db = firebase.firestore();
db.settings({timestampsInSnapshots: true})

생략 ~~

최신 버전의 Node.js를 사용하면 위와 같은 문제가 생기지 않지만,

마지막에 다룰 무료 호스팅(Firebase Hosting)Node.js 6을 지원한다. 최신 버전을 지원하지 않는다.






+ Recent posts