본문 바로가기
Today I Learned/Task

[Task] Express와 Firestore 연동하기

by YES_developNewbie 2024. 9. 20.

1. Express에서 firestore 설정

Express에서 firestore의 설정을 하는 방법은 firebase 공식문서에 나와있다. 하지만 나는 env 파일을 따로 만들어 필요 데이터를 저장하고 firebase config를 진행하였다.

.env 파일에 firestore에서 제공하는 config 데이터들을 넣어둔 후 아래와 같은 코드를 작성한다.

const dotenv = require('dotenv');
const assert = require('assert');

dotenv.config();

const {
    PORT,
    HOST,
    HOST_URL,
    API_KEY,
    AUTH_DOMAIN,
    DATABASE_URL,
    PROJECT_ID,
    STORAGE_BUCKET,
    MESSAGING_SENDER_ID,
    APP_ID
} = process.env;

assert(PORT, 'PORT is required');
assert(HOST, 'HOST is required');

module.exports = {
    port: PORT,
    host: HOST,
    url: HOST_URL,
    firebaseConfig: {
        apiKey: API_KEY,
        authDomain: AUTH_DOMAIN,
        databaseURL: DATABASE_URL,
        projectId: PROJECT_ID,
        storageBucket: STORAGE_BUCKET,
        messagingSenderId: MESSAGING_SENDER_ID,
        appId: APP_ID
    }
}

 

또한, db.js 파일을 생성하여 config파일과 다운로드한 firebase 라이버러리를 활용해 초기설정을 진행해준다.

const firebase = require('firebase');
const config = require('./config');

const db = firebase.initializeApp(config.firebaseConfig);

module.exports = db;

 

2. firstore에 데이터 넣기

유저가 회원가입을 함에 따라 유저의 정보를 데이터베이스에 넣는 작업을 함수로서 개발해보았다.

// memberController.js
// members -> memberId -> memberData
const signUp = async (req, res) => {
	const { id, password, nickname } = req.body;

	if (id.length === 0 || password.length === 0 || nickname.length === 0) {
		res.status(400).send("ID | PW | NICKNAME IS NULL");
		return;
	}

	const isExistMember = await isExistMemberById(id);
	if (isExistMember) {
		res.status(400).send("ID is exist");
		return;
	}

	const responseMember = await createMember({ id, password, nickname });

	if (responseMember === null) {
		res.status(400).send("Error creating by ID");
		return;
	}
    
	res.send(responseMember);
};

위 코드는 회원가입 처리를 요청하는 HTTP request가 왔을 때 실행되는 함수이다. 

// memberService.js
const createMember = async (member) => {
	try {
		await firestore
			.collection(COLLECTION_MEMBER)
			.doc(member.id)
			.set(member);
		return member;
	} catch (e) {
		console.log(e.message);
		return null;
	}
};

실질적으로 데이터를 데이터베이스에 저장하는 작업을 하는 함수이다. signUp 함수에서 호출될 때 인자값으로 회원가입 정보를 넣어줬으으므로 해당 데이터를 바탕으로 데이터베이스에 저장한다.

3. firestore에 있는 데이터 읽기

TMDB라는 영화 API 서비스와 연동하여 영화데이터를 가져오고, 사용자가 특정 영화에 좋아요를 누르면 좋아요된 영화의 아이디를 개별적으로 데이터베이스에 저장하고 읽어오는 방식으로 좋아요 기능을 구현했다.

// movieController.js

const getLikedMovies = async (req, res) => {
	try {
		const { memberId } = req.params;
		const likedMovies = await readLikedMovies(memberId);

		res.send(likedMovies);
	} catch (e) {
		console.log(e.message);
		res.status(400).send(e.message);
	}
};

 

클라이언트(프론트)에서 좋아요된 영화 목록을 요청할 떄 직접적으로 실행되는 함수이다.

// memberService.js
// members -> memberId  -> likedMovies
const readLikedMovies = async (memberId) => {
	try {
		const member = await firestore
			.collection(COLLECTION_MEMBER)
			.doc(memberId)
			.get();

		const likedMovieArray = [];
		let memberData = member.data();

		if (memberData[COLUMN_LIKEDMOVIES] !== undefined) {
			memberData[COLUMN_LIKEDMOVIES].forEach((doc) => {
				console.log("doc : ", doc);
				likedMovieArray.push(doc);
			});
		}

		return likedMovieArray;
	} catch (e) {
		console.log(e.message);
		return [];
	}
};

 

실질적으로 데이터베이스에 접근하여 데이터를 가져오는 함수이다.