์ํฉ
firebase firestore db์ ๋ฐ์ดํฐ๊ฐ ์ ๋ฐ์ดํธ๋๋ฉด, onDocumentWrite๋ผ๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ ๊ฑธ์ด๋์ด db์ ์๋ก์ด ์ปฌ๋ ์ ์ ์๋์ผ๋ก ์ ์ฅํ๊ฒ ํ๋ ์ฝ๋๋ฅผ ์ง๊ณ ์๋ค.
๊ทธ๋ฐ๋ฐ, ํ ์คํธ๋ฅผ ์ด๋ป๊ฒ ํด์ผํ๋๊ฑฐ์ง?
๋ก์ปฌํ๊ฒฝ์์ ๊ฐ๋ฐํ๊ณ ์๋ ์ฝ๋๊ฐ ์ ์๋๋๋์ง ํ์ธํ๊ณ ์ถ์๋๋ง๋ค ๋งค๋ฒ firebase์ ๋ฐฐํฌํด์ ์ผ์ผ์ด ํ์ธํด์ผํ๋๊ฑธ๊น?
๋ง๋ ์๋จ!!!

์ด๋ด๋ ์ค์ ์ด์๋๊ณ ์๋ db์๋ ๊ด๋ จ์์ด, ์์ฑํ ์ฝ๋๊ฐ ์ ๋๋ก ์๋ํ๋์ง ๋ก์ปฌ์์ ํ ์คํธํด๋ณผ ์ ์๋ `Firebase Emulator Suite`๋ผ๋ ์๋ฎฌ๋ ์ดํฐ๋ผ๋ ๋๊ตฌ๊ฐ ์๋ค.
๋ชฉํ
๋ก์ปฌํ๊ฒฝ์์ ์์ฑํ ํธ๋ฆฌ๊ฑฐ ์ฝ๋๊ฐ Firestore์ ์ ์ ์ฅ๋๋์ง ์๋ฎฌ๋ ์ดํฐ๋ก ํ ์คํธํด๋ณด๋ฉฐ ํ์ธํ๋ค.
Firebase Emulator Suite ์ผ๋ก ๋ก์ปฌ์์ ํ ์คํธํ๋ ๋ฒ
1. Firebase Emulator ์ค์น
ํฐ๋ฏธ๋์์ ์๋์ ๊ฐ์ด ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ค์นํ๋ค.
firebase setup:emulators:firestore
์๋์ฒ๋ผ init ๋ช ๋ น์ด๋ก ์ค์นํด๋ ๋ฌด๋ฐฉํ๋ค.
firebase init emulators
์ด ๊ฒฝ์ฐ ์๋์ ๊ฐ์ด ์ํ๋ Emulator๋ฅผ ์ ํ ๊ฐ๋ฅ.
=== Emulators Setup
? Which Firebase emulators do you want to set up? Press Space to select emulators, then Enter to confirm your choices. (Press
<space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
โฏ App Hosting Emulator
โฏโฏ Firestore Emulator
โฏโฏ Functions Emulator
โฏ Database Emulator
โฏ Hosting Emulator
โฏ Pub/Sub Emulator
โฏ Storage Emulator
โฏ Eventarc Emulator
๋๋ firestore์ functions๋ฅผ ํจ๊ป ํ ์คํธํด์ผํ๋ ๋ ๊ฐ์ง๋ฅผ ์ ํํ๋ค.
2. ์๋ฎฌ๋ ์ดํฐ ์คํ
ํ๋ก์ ํธ ๋ฃจํธ (package.json, firebase.json)์ด ์๋ ๊ฒฝ๋ก์์ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์คํํ๋ค.
firebase emulators:start --only firestore,functions
๊ทธ๋ผ ํฐ๋ฏธ๋์ ์ฑ๊ณตํ๋ค๊ณ ๋จ๊ณ ์๋ฎฌ๋ ์ดํฐ๊ฐ ์ผ์ง๋ค. ์๋์ ๊ฐ์ด ๋งํฌ๊ฐ ๋์จ๋ค.
๋งํฌ๋ฅผ ํ๊ณ ๋ค์ด๊ฐ๋ฉด ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ผ๋ฉด ์๋์ ๊ฐ์ด ๋ธ๋ผ์ฐ์ ์์ ์ธํฐํ์ด์ค๋ก ํ์ธ์ด ๊ฐ๋ฅํ๋ค.
3. ๊ธฐ์กด ์ฝ๋ (HTTP ํจ์) ํ ์คํธ ๋ฐฉ๋ฒ
์ฐ์ trigger ํจ์๋ฅผ ์์ฑํ๊ธฐ ์ด์ , ๊ธฐ์กด ๋ฒ์ ์ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
HTTP ํจ์(express)๋ ์ด๋ฏธ ๋ฐฐํฌ๊ฐ ๋์ด์๋ ์ํ์๊ณ , ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ์๋ค.
//server/firebase.json
//...
"functions": [
{
"source": ".",
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log",
"*.local"
],
"rewrites": [
{
"source": "**",
"function": "api"
}
],
"runtime": "nodejs22"
}
]
//...
`firebase.json`์์ `"functions"`์ `"source": "."` ๋ผ๊ณ ์ค์ ํด๋๋ค. ์ฆ, ์๋ฒ ํ๋ก์ ํธ root ๋๋ ํ ๋ฆฌ์์ firebase functions์ฝ๋๊ฐ ์คํ๋๋๋ก ์ค์ ํด๋ .
๋ํด์, `firebase.json`์์ `"rewrites"`์ค์ ์ ๋ณด๋ฉด ๋ชจ๋ ์์ฒญ์ `api`๋ผ๋ ๋ค์ด๋ฐ์ผ๋ก ๋ณด๋ด๊ณ ์๋ค. ์ฆ, ๋ชจ๋ HTTP ์์ฒญ ํจ์๋ `api`๋ผ๋ ์ด๋ฆ์ Firebase Functions๋ก ์ฐ๊ฒฐํ๋ผ๋ ๋ป ์ด๋ค.
๋ฌผ๋ก api ํจ์๋ ๋ฃจํธ ๋๋ ํ ๋ฆฌ ๋ด๋ถ์ ์ ์๊ฐ ๋์ด ์์ด์ผ ํ๋ค.
//server/src/index.ts
import express, { Express } from "express";
import { onRequest } from "firebase-functions/v2/https";
const app: Express = express();
//...
export const api = onRequest(app);
๋ฐ๋ผ์ ์์ ๊ฐ์ด ํ๋ก์ ํธ์๋ `src/index.ts`์ `api`๋ก ๋ค์ด๋ฐํ ํจ์๋ export ๋์ด์๋ค.
express ์ฑ์ firebase functions ๋ก ๋ํํด๋์์๋ค.
์, ๊ทธ๋ฆฌ๊ณ ๋์ ์ด์ํ์์ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ผ์ functions ๋ก๊ทธ๋ฅผ ๋ณด๋ฉด, ์๋์ ๊ฐ์ด ๋ฌ๋ค.
functions: Loaded functions definitions from source: api.
source: api ๊ฐ ์ฐํ๋ ๊ฒ์ ๋ณด๋ ์ฐ์ ์๋ฎฌ๋ ์ดํฐ๊ฐ ์ ์๋ํ๋ ๊ฑด ๋ง๋ค.
4. trigger ์ฝ๋ ํ ์คํธ ๋ฐฉ๋ฒ
ํธ๋ฆฌ๊ฑฐ ํจ์ ์์ฑ
firestore ํจ์ ํธ๋ฆฌ๊ฑฐ ๊ณต์๋ฌธ์ ์ฐธ๊ณ
//server/src/functions/triggers/waterCreated.ts
import { onDocumentWritten } from "firebase-functions/v2/firestore";
import { logger } from "firebase-functions/v2";
export const waterCreated = onDocumentWritten(
`${water์ปฌ๋ ์
์ด๋ฆ}/{documentId}`,
(event) => {
const snapshot = event.data;
if (!snapshot) {
logger.log("No data associated with the event");
return;
}
const newData = snapshot.after.data();
logger.log(newData, "๋ด๋ฐ์ดํฐ");
}
);
์๋ ํ์ด์ด์คํ ์ด์ ๋ด๊ฐ ์ง์ ํ ์ปฌ๋ ์ ์ด ์๋ก ์ ๋ฐ์ดํธ ๋ ๋๋ง๋ค ํธ์ถ๋๋ ํธ๋ฆฌ๊ฑฐ ํจ์์ด๋ค.
water๋ผ๋ ์์ธ๊ฐ์ด ๋ด๊ธด ์ปฌ๋ ์ ์ด ์ ๋ฐ์ดํธ๋๋ฉด, ํ์คํ ๋ฆฌ ๋ด์ญ ์ปฌ๋ ์ ์ ์๋ก ์์ฑํด์ water๋ผ๋ ์์ธ๊ฐ์์ ๋ฐ์ ๊ฐ์ ์๋ก์ด ํ๋๊ฐ์ผ๋ก ๊ฐ๊ณตํด์ ์๋ก db์ ์ ์ฅํ๋ ค๋ ๋ก์ง์ ์์ฑ ์์ ์ด๋ผ, ์ฐ์ ์๋ก ๋ค์ด์ค๋ ๋ฐ์ดํฐ๊ฐ ๋ก๊ทธ์ ์ ์ฐํ๋ ์ง ํ์ธํด๋ณด๋ ๋ก์ง์ด๋ค.
์ฌ๊ธฐ์, ์๋ฎฌ๋ ์ดํฐ์์ ๋ก๊ทธ๋ฅผ ํ์ธํด๋ณด๋ ค๋ฉด console.log๊ฐ ์๋ `logger.log`๋ก ํ์ธํด์ผํ๋ค.
ํ์ง๋ง ๋ก์ปฌ์์ ์ฝ๋๋ฅผ ๋ฐ๊พธ๊ณ , ์๋ฌด๋ฆฌ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์์ํ๊ณ Firestore ์๋ฎฌ๋ ์ดํฐ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํด๋ด๋, ์ ๋ก๊ทธ๋ ๋ณด์ด์ง ์์๋ค.
๋๋ฒ๊น
์ฌ๊ธฐ์..
triggerํจ์๋ apiํจ์๋ก ๋ณด๋ด์ผํ๋ ๊ฑด๊ฐ?๋ผ๊ณ ํท๊ฐ๋ฆฌ๊ธฐ ์์ํ๋ค.
ํ์ง๋ง, ํธ๋ฆฌ๊ฑฐ ํจ์๋ Firestore์ ๋ฐ์ดํฐ ๋ณํ๋ก ์๋ ํธ์ถ๋๋ ํจ์์ด๊ธฐ๋๋ฌธ์ api ํจ์์๋ ๋ฌด๊ดํ๋ค.
๊ทธ๋ ๋ค๋ฉด?
trigger ํจ์๊ฐ functions์ ์์ง ๋ฑ๋ก์ด ์๋๊ฑฐ๋ค.
์ฆ, ํธ๋ฆฌ๊ฑฐํจ์๋ฅผ ์ค์ export ํด์ค์ผ์ง firebase functions์์ ํธ๋ฆฌ๊ฑฐ ํจ์๋ฅผ ์ธ์ํ ์ ์๋ค.
ํธ๋ฆฌ๊ฑฐ ํจ์ export ์ํค๊ธฐ
`src/index.ts`์ ์๋์ ๊ฐ์ด ์์ ๊ฐ์ด ์ ์ด์ค ํธ๋ฆฌ๊ฑฐํจ์๋ฅผ export ์์ผ์ผํ๋ค.
//server/src/index.ts
export { waterCreated } from "./functions/triggers/waterCreated";
trigger ํจ์๋ ๊ทธ๋ฅ export๋ง ํด๋๊ณ , Firebase๊ฐ ์ง์ ๊ฐ์งํด์ Firestore ๋ณ๊ฒฝ๋ ๋ ์คํ์ํจ๋ค.
๋ฒ์ธ๋ก ์๊ธฐํ์๋ฉด ๋๋ ์ฌ๊ธฐ์ ๋๋ฒ๊น ์ด ๋ ์์ฒญ ์ค๋๊ฑธ๋ ธ๋๋ฐ..
์๋ฒํ๋ก์ ํธ/
โโโ src/
โ โโโ index.ts <- Firebase Emulator๊ฐ ์ฝ๋ ์ง์ง index
โ โโโ functions/
โ โโโ triggers/
โ โโโ waterCreated.ts
โโโ firebase.json
โโโ package.json
๋ด `firebase.json`์์ ์ ์ด๋ ์ฝ๋์ฒ๋ผ functions์ source๊ฐ `"."` (root) ์ด๊ธฐ ๋๋ฌธ์ ํ์ด์ด๋ฒ ์ด์ค๊ฐ ๋ณด๊ณ ์๋๊ฑด ๋ฃจํธ๋๋ ํ ๋ฆฌ์ด๋ค.
ํ์ด์ด๋ฒ ์ด์ค๋ ๊ธฐ๋ณธ์ ์ผ๋ก `firebase.json`์ `source` ์ค์ ์ ๊ธฐ์ค์ผ๋ก functions ๋ฅผ ์ด๋์ ์ฐพ์์ผ ํ ์ง๋ฅผ ํ๋จํ๊ธฐ๋๋ฌธ์ Firebase๊ฐ ์ง์ ์ฝ๋ ํ์ผ์ ์ค์ง `src/index.ts`๋ผ๋ ๊ฑฐ๋ค.
๊ทผ๋ฐ ์ด๊ฑธ ์ ํํ ๋ชฐ๋ผ์ ํธ๋ฆฌ๊ฑฐํจ์๋ฅผ ๋ค๋ฅธ๋ฐ์ export ํ์์๋ค;;
`firebase.json`์ ์ ์ํ๋๋ก `functions`์ `source` ์ค์ ์ ๊ธฐ์ค์ผ๋ก ๊ทธ ๋๋ ํ ๋ฆฌ์์ export๋ฅผ ํด์ค์ผ ํ์ด์ด๋ฒ ์ด์ค๊ฐ ์ฝ์ ์ ์๋ค!!!!
์, ์ด๋ ๊ฒ ๋ฐ๊พธ๊ณ ๋ค์ ํ๋ฒ `firebase emulators:start --only firestore,functions`๋ก ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์คํํ๋ค.
๊ทผ๋ฐ.. ์ฌ์ ํ ์๋จ..
์ด์ด์๊ฒ๋ ๋น์ฐํ๊ฑธ ๋์ณค๋ค.
๋น๋ํ๊ธฐ
- ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์์ํ๊ธฐ ์ ์ tsc ๋น๋๋ฅผ ๋จผ์ ํด์ผํ๋ค.
- ์๋ก ์์ฑํ trigger ํจ์๋ฅผ ๋น๋ํด์ผ์ง ์๋ก์ด ์ฝ๋๋ฅผ ์๋ฎฌ๋ ์ดํฐ๊ฐ ์ฝ์ ์ ์๋ค.
์๋ฎฌ๋ ์ดํฐ์์ ๋๋ฆฌ๋ ค๋ฉด ๋น๋๊ฐ ํ์ํ ์ด์ ?
- TypeScript๋ ๋ธ๋ผ์ฐ์ ๋ Node.js๊ฐ ๋ฐ๋ก ์ดํดํ ์ ์๋ค.
→ Node.js (์๋ฎฌ๋ ์ดํฐ ํฌํจ)๋ .ts ํ์ผ์ ์คํํ ์ ์๊ณ .js ํ์ผ๋ง ์คํํ ์ ์๋ค. - tsc(๋๋ npm run build)๋ TypeScript๋ฅผ JavaScript๋ก ๋ณํํ๋ ์์
์ด๋ค.
→ ๋น๋ํ๋ฉด src/index.ts ๊ฐ์ ํ์ผ์ด dist/index.js ๊ฐ์ ์คํ ๊ฐ๋ฅํ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ๋ก ๋ฐ๋๋ค. - Firebase Emulator๋ ๋น๋๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ์คํํ๋ค.
→ ์๋ฎฌ๋ ์ดํฐ๊ฐ dist/ํด๋ ๊ฐ์ ๋ฐ์ .js ํ์ผ์ ์ฝ์ด ์คํํ๋ ๊ตฌ์กฐ์ด๋ค.
(์์ฑ) src/index.ts --[tsc ๋น๋]--> (๋ณํ) dist/index.js
src/ → ๋ด๊ฐ ๊ฐ๋ฐํ๋ ๊ณณ (TypeScript, ์ต์ ๋ฌธ๋ฒ ์ฌ์ฉ ๊ฐ๋ฅ)
dist/ → ์ค์ ๋ก ์๋ฎฌ๋ ์ดํฐ/์๋ฒ๊ฐ ์คํํ๋ ๊ณณ (Node.js๊ฐ ์ฝ์ ์ ์๋ JS)
"์๋ฎฌ๋ ์ดํฐ = ์๋ฐ์คํฌ๋ฆฝํธ(.js) ํ์ผ๋ง ์ฝ๋๋ค" → ๊ทธ๋์ ๋งค๋ฒ ๋น๋๊ฐ ํ์ํ๋ค.
์๋ฎฌ๋ ์ดํฐ ์คํํ๊ธฐ
firebase emulators:start --only firestore,functions
์ ๋ช ๋ น์ด๋ก ๋ค์ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์คํํด์ค๋ค.
๋ฐ๋ผ์, ์ ์ ์๋ํ๋ ํ๋ก์ฐ๋ฅผ ์ ๋ฆฌํ๋ฉด ์๋์ ๊ฐ๋ค.
์ ๋ฆฌ
๐ ์ ๋ฆฌ๋ "์ ์ ์๋ ํ๋ก์ฐ"
- trigger ํ์ผ ๋ด๋ถ onDocumentWritten ์ ํํ ์์ฑ (v2 ๋ฒ์ ๋ฌธ๋ฒ์ผ๋ก ์ฌ์ฉ)
- src/index.ts์์ export (`firebase.json`์ ์ ์ํ๋๋ก `functions`์ `source` ์ค์ ์ ๊ธฐ์ค์ผ๋ก exportํ๊ธฐ)
- tsconfig ์ค์ ์ ๊ฒ (src ๊ธฐ์ค์ผ๋ก ์ปดํ์ผํ๋๋ก ์ธํ ๋์ด์๋์ง, module ์ค์ ์ด "commonjs" ํน์ "esnext"๋ก ๋์ด์๋์ง ํ์ธ)
- npm run build
- firebase emulators:start (๋น๋ ํ ๋งค๋ฒ ์๋ฎฌ๋ ์ดํฐ ์ฌ ์คํ)
- ๋ก๋ฉ ๋ก๊ทธ ํ์ธ
์ด๋ ๊ฒ ์ ๋๋ก ํ๋ค๋ฉด, ์๋์ ๊ฐ์ด ์๋ฎฌ๋ ์ดํฐ Functions ๋ก๊ทธ์๋ ํธ๋ฆฌ๊ฑฐ ํจ์๊น์ง ์ ๋ก๋๊ฐ ๋์๋ค๊ณ ์ฐํ๋ค.
์๋์ ๊ฐ์ด functions: Loaded functions definitions from source: waterCreated. ์ด๋ฐ ๋ก๊ทธ๊ฐ ์ ์ฐํ๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
Firestore ์๋ฎฌ๋ ์ดํฐ์์๋ ๋ด๊ฐ ์ํ๋๋๋ก water๋ผ๋ ์ปฌ๋ ์ ์ ์์ธ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ผ๋ฉด, (ํธ๋ฆฌ๊ฑฐํจ์๊ฐ ํธ์ถ๋๋ฉด์) ์ ์ ๋ก histories๋ผ๋ ์ปฌ๋ ์ ์ ๋ฐ์ดํฐ๊ฐ ์๋ก ์ถ๊ฐ๋๋ ๊ฒ์ ๋์ผ๋ก ์ง์ ํ์ธํด ๋ณผ ์ ์๋ค.
๐๐๐
๋
'Firebase' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Firebase ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง๋ค๊ธฐ node ์๋ฒ์์ db ์ ๊ทผํ๊ธฐ (0) | 2024.11.07 |
---|---|
firebase๋ก ํ๋ก ํธ ์น์ฑ ๋ฐฐํฌ (0) | 2024.10.28 |