Firebase Cloud Functions는 관리형 Node.js 환경에서 코드를 실행하기 위한 서버 측 플랫폼으로, Firebase 이벤트, HTTPS 요청 및 Google Cloud 서비스의 변경 사항에 응답합니다. 기존 백엔드와 달리 개발자는 서버를 구성하거나 웹 서버를 설치하거나 확장에 대해 걱정할 필요가 없습니다. 각 함수는 격리된 컨테이너에서 실행되며 필요한 리소스를 자동으로 얻습니다. Google Firebase(2026)에 따르면, 이 플랫폼은 매일 20억 회 이상의 함수 호출을 처리하며 수백만 개의 모바일 애플리케이션에 서버리스 아키텍처를 제공합니다.
핵심 사항
Firebase Cloud Functions는 Google Cloud Functions(GCF) 위에 구축된 컴퓨팅 플랫폼으로, Firebase 생태계에 맞게 조정되었습니다. 함수는 모듈에서 내보내고 특정 이벤트 유형에 등록된 일반 JavaScript 또는 TypeScript 코드입니다. 이벤트가 발생하면(예: 사용자가 등록하거나 파일을 업로드하면) Firebase Cloud Functions가 해당 코드를 실행하고 이벤트 컨텍스트를 전달합니다.
Cloud Functions 아키텍처는 단일 책임 원칙을 따릅니다. 하나의 함수가 하나의 이벤트 유형을 처리하고 하나의 원자적 작업을 수행합니다. 예를 들어, sendWelcomeEmail 함수는 Firebase Authentication에서 새 사용자가 생성될 때 트리거되어 환영 이메일을 보냅니다. 이러한 분리는 디버깅, 테스트 및 여러 프로젝트에서 함수 재사용을 간소화합니다.
각 함수는 임시 수명 주기를 가진 격리된 컨테이너에서 실행됩니다. 최대 실행 시간은 기본적으로 60초입니다(HTTPS 함수 — 9분). 함수가 제한 시간 내에 완료되지 않으면 요청이 오류 500으로 실패합니다. 장기 실행 작업의 경우 재시도와 함께 Cloud Tasks 또는 Pub/Sub를 사용하세요. 컨테이너는 후속 호출에 재사용(keep-alive)될 수 있어 첫 번째 호출 후 콜드 스타트 지연 시간을 줄입니다.
Firebase Cloud Functions는 여러 Node.js 버전(18, 20, 22(새 프로젝트에 권장))을 지원합니다. 버전은 package.json 파일의 engines 필드에 지정됩니다. Firebase CLI는 지정된 버전에 따라 런타임 환경을 자동으로 구성합니다. 중요: Firebase Cloud Functions는 임의의 Docker 컨테이너 실행을 지원하지 않습니다. 환경은 Google Cloud Functions에 의해 엄격하게 고정됩니다.
새 프로젝트의 경우 Node.js 22를 권장합니다. 최신 V8 최적화, 개선된 ESM 모듈 지원 및 플랫폼 수준의 WebSocket 지원이 포함되어 있기 때문입니다. 특정 Node 버전용으로 빌드된 종속성(예: 네이티브 C++ 모듈)을 사용하는 프로젝트는 호환성을 개별적으로 확인해야 합니다. 모든 네이티브 모듈이 GCF 환경에서 컴파일되는 것은 아닙니다.
Firebase Cloud Functions는 Firebase SDK가 사전 설치되고 Firebase 서비스와 통합된 Google Cloud Functions의 래퍼입니다. 개발자는 firebase-functions SDK를 사용하여 코드를 작성하며, 이 SDK는 모든 Firebase 서비스에 대해 유형화된 트리거를 제공합니다. Google Cloud Functions는 트리거가 Eventarc 또는 Pub/Sub를 통해 명시적으로 구성되는 더 낮은 수준의 플랫폼입니다.
주요 차이점: Firebase Cloud Functions에서는 트리거가 functions.firestore.document('path').onWrite()를 통해 선언적으로 등록되지만, Google Cloud Functions에서는 이벤트 속성 필터링과 함께 Eventarc를 통해 구성됩니다. Firebase Cloud Functions에는 프로젝트의 서비스 계정 자격 증명으로 자동 초기화되는 Admin SDK도 함께 제공되어 추가 설정 없이 모든 Firebase 서비스에 대한 전체 액세스를 제공합니다.
Firebase Cloud Functions는 8개 범주의 트리거를 지원하며, 각각 특정 Firebase 또는 Google Cloud 서비스에 해당합니다. 트리거는 조건이 충족되면 자동으로 함수를 호출하는 조건입니다. 개발자는 함수 수명 주기를 직접 관리하지 않습니다. Firebase CLI가 Google Cloud Eventarc에 트리거를 등록하면 이벤트가 발생할 때 클라우드 플랫폼이 함수를 실행합니다.
가장 인기 있는 트리거는 Firestore 트리거(onWrite, onCreate, onUpdate, onDelete)입니다. Firestore 컬렉션의 문서가 변경되면 트리거됩니다. 함수는 변경 전후의 문서 스냅샷을 수신하므로 값을 비교하고 특정 변경에만 응답할 수 있습니다. 예를 들어, 주문 상태가 “보류 중”에서 “발송됨”으로 변경되면 사용자에게 푸시 알림을 보낼 수 있습니다.
Authentication 트리거(onCreate, onDelete)는 사용자 계정이 생성되거나 삭제될 때 트리거됩니다. 사용자 데이터 초기화(Firestore에 사용자 문서 생성, 환영 이메일 보내기, 분석에 기록)에 사용됩니다. 참고: 함수는 사용자 생성을 취소할 수 없습니다. 계정이 이미 생성된 후에 실행됩니다. 사전 검증을 위해 Identity Platform에서 사용 가능한 Blocking Functions를 사용하세요.
| 트리거 범주 | 이벤트 | 사용 예 |
|---|---|---|
| Firestore | onWrite, onCreate, onUpdate, onDelete | 좋아요 추가 시 좋아요 카운터 업데이트 |
| Authentication | onCreate, onDelete | 등록 시 사용자 프로필 생성 |
| Realtime DB | onWrite, onCreate, onUpdate, onDelete | 채팅 메시지 중재 |
| Storage | onFinalize, onArchive, onDelete | 이미지 업로드 후 썸네일 생성 |
| Pub/Sub | onPublish | Cloud Scheduler를 통한 예약 실행(cron) |
| HTTPS | onRequest | 외부 서비스를 위한 REST API 엔드포인트 |
HTTPS 함수(onRequest)를 사용하면 HTTP를 통해 액세스할 수 있는 완전한 REST API 엔드포인트를 만들 수 있습니다. 이벤트 기반 트리거와 달리 HTTPS 함수는 https://{region}-{project}.cloudfunctions.net/{functionName} 형식의 URL을 통해 호출됩니다. 엔드포인트가 브라우저나 모바일 애플리케이션에서 호출되는 경우 CORS를 올바르게 구성하는 것이 중요합니다. Firebase SDK는 자동으로 CORS 헤더를 포함하지 않으므로 미들웨어를 통해 수동으로 추가해야 합니다.
모바일 클라이언트(Android, iOS)의 경우 네이티브 HTTP 클라이언트가 교차 출처 정책에 의해 제한되지 않으므로 CORS가 필요하지 않습니다. CORS는 웹 요청에만 관련됩니다. HTTPS 함수가 앱과 웹 모두에서 호출되는 경우 개발용으로 res.set('Access-Control-Allow-Origin', '*') 또는 프로덕션용으로 허용된 도메인 목록을 사용하여 범용 CORS 처리를 추가하세요.
정기적 실행(cron 작업)의 경우 Cloud Scheduler와 Pub/Sub의 조합을 사용하세요. Cloud Scheduler가 일정에 따라 Pub/Sub 주제에 메시지를 보내면 Cloud Functions의 onPublish 트리거가 해당 메시지를 처리합니다. Firebase CLI는 직접적인 cron 구문을 지원하지 않습니다. 일정은 Google Cloud 콘솔 또는 Terraform을 통해 unix-cron 형식(0 3 * * *(매일 3:00))으로 구성됩니다.
작업 예: 일일 뉴스레터, 오래된 데이터 정리, 보고서 생성, 외부 API와의 동기화. 중요: Cloud Scheduler는 Google Cloud의 유료 서비스입니다(작업당 월 약 $2). 각 트리거는 별도의 함수 호출로 계산되며 표준 Cloud Functions 요금으로 청구됩니다.
Cloud Functions 개발은 Firebase CLI를 통해 프로젝트를 초기화하는 것으로 시작됩니다: firebase init functions. 이 명령은 index.js(또는 index.ts) 템플릿, package.json 파일 및 TypeScript 구성(선택한 경우)이 포함된 functions/ 디렉토리를 생성합니다. 초기화 후 함수를 작성하고 모듈에서 내보낸 다음 firebase deploy --only functions를 실행하여 배포하기만 하면 됩니다.
각 함수는 적절한 트리거 메서드를 호출하여 등록됩니다. HTTPS 함수의 예: exports.helloWorld = functions.https.onRequest((req, res) => { res.send(“Hello!”); }). Firebase Functions는 비동기 모델을 사용합니다. 이벤트 기반 트리거(비HTTPS)의 경우 함수는 Promise를 반환해야 합니다. Firebase는 컨테이너를 종료하기 전에 Promise가 완료될 때까지 기다립니다. Promise가 반환되지 않으면 비동기 작업이 완료되기 전에 함수가 종료될 수 있습니다.
로컬 개발은 Cloud Functions 에뮬레이터가 포함된 Firebase Emulator Suite를 통해 수행됩니다. firebase emulators:start 명령은 http://localhost:5001에서 액세스 가능한 함수와 함께 로컬 서버를 시작합니다. 에뮬레이터는 코드 변경 시 핫 리로드를 지원하며 프로덕션 환경과 완전히 격리되어 실제 데이터를 위험에 빠뜨리지 않고 테스트할 수 있습니다.
Cloud Functions의 종속성은 package.json을 통해 관리됩니다. Firebase는 프로덕션 종속성(dependencies, devDependencies 제외)만 설치합니다. 함수 패키지 크기는 콜드 스타트 시간에 영향을 미치므로 종속성 수를 최소화하는 것이 좋습니다. Firebase Admin SDK의 firebase-admin 종속성은 사전 설치되어 있으므로 수동으로 추가할 필요가 없습니다.
기밀 데이터(API 키, 토큰)는 함수 코드에 저장하면 안 됩니다. 구성을 저장하려면 functions.config()를 사용하세요: firebase functions:config:set stripe.key=“sk_...”. 값은 암호화되어 functions.config().stripe.key를 통해 런타임에 사용할 수 있습니다. 대규모 직렬화 구성의 경우 Google Cloud Secret Manager를 사용하세요.
Cloud Functions의 로깅은 console.log, console.warn 및 console.error를 통해 수행됩니다. 모든 로그는 자동으로 Google Cloud Logging에 수집되어 Firebase 콘솔(Functions > Logs)에서 확인할 수 있습니다. 구조화된 로깅을 위해 JSON 형식 및 로그 수준을 지원하는 winston 또는 pino 라이브러리를 사용하세요.
오류 처리는 안정성에 매우 중요합니다. Promise에서 처리되지 않은 예외는 오류와 함께 함수를 종료하고 Firebase는 지수 백오프로 자동 재시도합니다. 재시도 횟수는 0에서 무한대까지 구성 가능합니다. 이벤트 기반 트리거의 경우 외부 서비스의 일시적인 장애 중에도 모든 이벤트가 처리되도록 재시도를 활성화하는 것이 좋습니다.
콜드 스타트는 비활성 기간 후 함수를 처음 호출할 때 코드가 포함된 컨테이너를 다시 로드하고 초기화하는 지연입니다. Firebase 문서(2026)에 따르면 콜드 스타트는 패키지 크기, 종속성 수 및 지역에 따라 200ms에서 2초까지 걸립니다. 사용자 인터페이스의 경우 1초를 초과하는 지연은 눈에 띄며 사용자 경험에 영향을 줄 수 있습니다.
콜드 스타트 최소화 방법: 종속성 최소화, CommonJS로 컴파일된 TypeScript 사용, 함수 패키지 크기 축소, 최소 활성 인스턴스 수 설정. Firebase Cloud Functions v2(2세대)는 minInstances(항상 요청을 처리할 준비가 된 웜 컨테이너의 최소 수)를 설정할 수 있습니다. 컨테이너를 웜 상태로 유지하면 유휴 시간에 대한 비용이 발생합니다.
Cloud Functions의 확장은 자동으로 이루어집니다. 요청량이 증가하면 Firebase가 새 컨테이너를 만듭니다. 기본적으로 최대 병렬 인스턴스 수는 3000입니다(Google Cloud 프로젝트 할당량). 각 인스턴스는 한 번에 하나의 요청을 처리합니다. 함수가 빠른 경우(100ms 미만) 하나의 인스턴스가 초당 최대 10개의 요청을 처리할 수 있어 프로젝트당 초당 최대 30,000개의 요청 처리량을 제공합니다.
minInstances는 지정된 수의 컨테이너를 예약하고 웜 상태로 유지하는 매개변수입니다. 콜드 스타트 지연이 허용되지 않는 중요한 HTTPS 함수에 권장됩니다. 예를 들어 인증 엔드포인트의 경우 minInstances: 1을 설정하세요. maxInstances는 최대 병렬 인스턴스 수를 제한하여 갑작스러운 트래픽 급증 시 통제할 수 없는 비용 증가를 방지하는 데 유용합니다.
구성은 코드에서 수행됩니다: functions.runWith({ minInstances: 1, maxInstances: 10 }). 중요: minInstances는 컨테이너가 지속적으로 실행되므로 비용이 증가합니다. 테스트 프로젝트의 경우 minInstances를 비활성화해야 합니다. 프로덕션의 경우 모든 공개 HTTPS 함수에는 minInstances를 권장하고 1초 지연이 중요하지 않은 이벤트 기반 트리거에는 0을 권장합니다.
배포 지역은 최종 사용자에 대한 지연 시간과 발신 트래픽 비용에 영향을 미칩니다. Firebase Cloud Functions는 30개 이상의 Google Cloud 지역에서 사용 가능합니다. 모바일 애플리케이션의 경우 대상 고객과 가장 가까운 지역을 선택하세요: 미주의 경우 us-central1, 유럽의 경우 europe-west1, 아시아의 경우 asia-east2. 지역은 함수를 재배포하지 않고는 변경할 수 없습니다.
지역 변경은 코드에서 region 매개변수를 통해 수행됩니다: functions.region('europe-west1'). 하나의 파일에 있는 모든 함수는 서로 다른 지역을 가질 수 있습니다. 글로벌 프로젝트의 경우 여러 지역에 함수를 배포하고 Cloud Load Balancing을 사용하여 트래픽을 분산하는 것이 좋지만, 대부분의 모바일 애플리케이션의 경우 올바르게 선택하면 단일 지역으로 충분합니다.
TypeScript로 된 Cloud Functions의 실용적인 예제를 살펴보겠습니다. 코드는 ES 모듈 구문과 함께 Firebase Functions SDK v2(2세대)를 사용합니다. 예제에는 사용자 생성 이벤트 처리, 이미지 업로드 시 썸네일 생성, REST API용 간단한 HTTPS 엔드포인트가 포함됩니다. 모든 함수는 비동기이며 올바른 컨테이너 종료를 위해 Promise를 반환합니다.
실행하기 전에 Firebase CLI가 버전 13+로 업데이트되었는지 확인하세요: npm install -g firebase-tools. v2 함수에는 Blaze 요금제가 필요합니다. 초기화: TypeScript를 선택한 firebase init functions.
첫 번째 예제는 새 사용자가 등록할 때 Firestore에서 문서 생성입니다. 함수는 auth.user().onCreate 이벤트에 의해 트리거되어 users/{uid} 컬렉션에 기본 프로필을 작성합니다. 이를 통해 등록된 각 사용자에게 필요한 필드가 있는 문서가 있게 됩니다.
import * as functions from "firebase-functions"
import * as admin from "firebase-admin"
admin.initializeApp()
export const createUserProfile = functions.auth
.user()
.onCreate(async (user) => {
const profile = {
email: user.email,
displayName: user.displayName ?? "User",
createdAt: admin.firestore.Timestamp.now(),
role: "free",
avatarUrl: null,
}
await admin.firestore()
.collection("users")
.doc(user.uid)
.set(profile)
console.log(`Profile created for ${user.uid}`)
})
createUserProfile 함수는 비동기입니다. Firebase가 종료 전에 기다리는 Promise를 반환합니다. Firestore에 쓰기가 실패하면(예: 권한 부족) 함수가 자동으로 재시도됩니다(재시도가 활성화된 경우). “free” 값의 role 필드는 resource.data.role을 필요한 액세스 수준과 비교하여 Firestore Security Rules에서 직접 무료 요금제 제한을 구현할 수 있습니다.
두 번째 예제는 이미지 업로드 후 자동으로 썸네일을 생성하는 Storage 트리거입니다. 함수는 200×200픽셀의 축소된 복사본을 만들어 thumb_ 접두사와 함께 원본 파일 경로에 저장합니다. 이미지 처리는 sharp 라이브러리를 사용하며, 모든 일반 형식을 지원하고 시스템 종속성 없이 Node.js 환경에서 작동합니다.
import * as path from "path"
import * as os from "os"
import * as sharp from "sharp"
export const generateThumbnail = functions.storage
.object()
.onFinalize(async (object) => {
if (!object.contentType?.startsWith("image/")) return
const filePath = object.name!
const thumbPath = filePath.replace(
/(\.\w+)$/, "_thumb$1"
)
const bucket = admin.storage().bucket()
const tempDir = os.tmpdir()
const tempFile = path.join(tempDir, path.basename(filePath))
await bucket.file(filePath).download({ destination: tempFile })
await sharp(tempFile)
.resize(200, 200, { fit: "cover" })
.toFile(tempFile.replace(/(\.\w+)$/, "_thumb$1"))
await bucket.upload(tempFile.replace(
/(\.\w+)$/, "_thumb$1"
), { destination: thumbPath })
})
generateThumbnail 함수는 객체의 Content-Type을 확인하고 이미지가 아닌 것은 무시하여 리소스를 절약합니다. sharp를 사용하려면 package.json에 종속성을 추가해야 합니다. 썸네일은 fit: “cover” 매개변수로 생성되어 이미지를 중앙에서 200×200픽셀 정사각형으로 자릅니다. 생성 후 썸네일은 수정된 이름으로 동일한 버킷에 다시 업로드됩니다.
세 번째 예제는 서버 상태 확인을 위한 REST API 엔드포인트를 구현하는 HTTPS 함수입니다. 함수는 GET 요청을 수락하고 프로젝트에 연결된 Firebase 서비스 상태에 대한 JSON을 반환합니다. 이 엔드포인트는 데이터를 보내기 전에 백엔드 가용성을 확인해야 하는 모니터링 및 외부 시스템에 유용합니다.
import * as express from "express"
const app = express.Router()
app.get("/status", async (req, res) => {
try {
const db = admin.firestore()
await db.collection("_health").doc("check").get()
res.json({ status: "ok", timestamp: Date.now() })
} catch (error) {
res.status(503).json({ status: "error", message: error })
}
})
export const api = functions.https.onRequest(app)
api 함수는 라우팅에 express Router를 사용하여 하나의 함수에서 여러 엔드포인트를 만들 때 편리합니다. 상태 확인은 _health 컬렉션의 Firestore에 기록하여 Firestore 가용성을 동시에 확인할 수 있습니다. 프로덕션의 경우 공개 엔드포인트의 남용을 방지하기 위해 API 키 또는 Firebase Auth 토큰을 통한 요청 인증을 추가하는 것이 좋습니다.
Cloud Functions는 클라이언트에서 수행할 수 없거나 수행해서는 안 되는 작업에 가장 일반적으로 사용됩니다: 푸시 알림 보내기, 업로드된 이미지 미리보기 생성, 외부 결제 시스템 통합, 콘텐츠 중재, Firebase와 타사 서비스 간 데이터 동기화. 서버리스 모델은 이러한 작업을 비용 효율적으로 만듭니다. 실제 코드 실행 시간에 대해서만 비용을 지불합니다.
결제 시스템 통합은 인앱 구매가 있는 앱의 일반적인 시나리오입니다. Cloud Functions는 결제 제공업체(Stripe, PayPal)로부터 웹훅을 수신하고 요청 서명을 확인하며 Firestore의 구독 상태를 업데이트하고 사용자에게 확인을 보냅니다. 모든 코드는 서버에서 실행되므로 클라이언트에서 데이터 변조 위험이 없습니다. Stripe 문서(2026)에 따르면 웹훅 처리는 500ms 미만이 소요됩니다.
스마트 콘텐츠 중재는 Cloud Function Storage 트리거를 사용하여 Google Cloud Vision API를 통해 업로드된 이미지를 자동으로 확인합니다. 함수는 안전하지 않은 콘텐츠(폭력, 성인 콘텐츠) 탐지를 위해 Vision API에 이미지를 보내고 임계값을 초과하면 파일을 삭제하고 관리자에게 알립니다. 이 시나리오는 사용자 갤러리가 있는 UGC 애플리케이션에 중요합니다.
데이터 집계 — Firebase Realtime Database 카운터를 대체하는 Cloud Functions. 클라이언트에서 카운터를 읽고 쓰는 것(경쟁 상태 유발) 대신 Firestore onWrite 트리거를 사용하여 집계된 필드를 원자적으로 업데이트합니다. 예를 들어, 함수는 /posts/{postId}/likes/{userId} 하위 컬렉션에서 문서가 추가되거나 제거될 때마다 게시물 좋아요 수를 계산하고 부모 문서의 likesCount 필드를 업데이트합니다.
자주 묻는 질문
최대 실행 시간은 유형에 따라 다릅니다: HTTPS 함수 — 9분, 이벤트 기반 트리거 — 60초(v2: 최대 60분). 장기 실행 작업의 경우 비동기 처리와 함께 Cloud Tasks 또는 Pub/Sub를 사용하세요. 제한 시간은 코드에서 runWith({ timeoutSeconds: 120 })를 통해 구성됩니다.
Firebase Emulator Suite를 사용하세요: firebase emulators:start --only functions. 에뮬레이터는 핫 리로드를 지원하며 포트 5001에서 로컬로 함수를 실행합니다. Firestore 및 Auth 트리거의 경우 에뮬레이터가 실제 서비스를 대체하여 프로덕션 데이터를 위험에 빠뜨리지 않고 시나리오를 테스트할 수 있습니다.
2세대는 Google Cloud Run과 Eventarc를 사용하여 더 긴 제한 시간(최대 60분), 단일 인스턴스에 의한 동시 요청 처리 및 Google Cloud 서비스와의 개선된 통합을 제공합니다. 1세대는 Google Cloud Functions를 사용하며 이벤트 기반 함수의 경우 60초로 제한됩니다. Firebase는 새 프로젝트를 2세대로 시작할 것을 권장합니다.
Firebase Cloud Functions는 공식적으로 Node.js(JavaScript 및 TypeScript)만 지원합니다. Python의 경우 Python용 Firebase Admin SDK와 함께 Google Cloud Functions를 직접 사용하세요. Firebase Admin SDK Python은 Node.js를 통해서만 사용할 수 있는 일부 Firebase 특정 트리거를 제외한 모든 작업을 지원합니다.
인증된 액세스의 경우 Authorization 헤더에서 Firebase ID 토큰을 확인하세요: admin.auth().verifyIdToken(token). 서버 간 통합의 경우 서비스 계정 또는 API 키와 함께 Firebase Admin SDK를 사용하세요. 속도 제한이 있는 공개 엔드포인트의 경우 Cloud Armor 또는 미들웨어를 통한 속도 제한을 사용하세요.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.