Cloud Functions를 시작하려면 필요한 설정 작업부터 시작하여 두 가지 관련 함수를 만들고, 테스트하고, 배포하는 과정으로 구성된 이 튜토리얼을 따라 수행해 보세요.
- 'add message' 함수: 텍스트 값이 허용되는 URL을 노출하고 Cloud Firestore에 이 값을 씁니다.
- 'make uppercase' 함수: Cloud Firestore 쓰기에서 트리거하고 텍스트를 대문자로 변환합니다.
다음은 함수가 포함된 전체 샘플 코드입니다.
Node.js
// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");
initializeApp();
// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
// Grab the text parameter.
const original = req.query.text;
// Push the new message into Firestore using the Firebase Admin SDK.
const writeResult = await getFirestore()
.collection("messages")
.add({original: original});
// Send back a message that we've successfully written the message
res.json({result: `Message with ID: ${writeResult.id} added.`});
});
// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
// Grab the current value of what was written to Firestore.
const original = event.data.data().original;
// Access the parameter `{documentId}` with `event.params`
logger.log("Uppercasing", event.params.documentId, original);
const uppercase = original.toUpperCase();
// You must return a Promise when performing
// asynchronous tasks inside a function
// such as writing to Firestore.
// Setting an 'uppercase' field in Firestore document returns a Promise.
return event.data.ref.set({uppercase}, {merge: true});
});
Python
# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn
# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore
app = initialize_app()
@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
"""Take the text parameter passed to this HTTP endpoint and insert it into
a new document in the messages collection."""
# Grab the text parameter.
original = req.args.get("text")
if original is None:
return https_fn.Response("No text parameter provided", status=400)
firestore_client: google.cloud.firestore.Client = firestore.client()
# Push the new message into Cloud Firestore using the Firebase Admin SDK.
_, doc_ref = firestore_client.collection("messages").add({"original": original})
# Send back a message that we've successfully written the message
return https_fn.Response(f"Message with ID {doc_ref.id} added.")
@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
"""Listens for new documents to be added to /messages. If the document has
an "original" field, creates an "uppercase" field containg the contents of
"original" in upper case."""
# Get the value of "original" if it exists.
if event.data is None:
return
try:
original = event.data.get("original")
except KeyError:
# No "original" field, so do nothing.
return
# Set the "uppercase" field.
print(f"Uppercasing {event.params['pushId']}: {original}")
upper = original.upper()
event.data.reference.update({"uppercase": upper})
이 가이드 정보
이 샘플에서는 Cloud Firestore 및 HTTP 트리거 함수를 선택했습니다. 이러한 백그라운드 트리거를 Firebase Local Emulator Suite를 통해 철저하게 테스트할 수 있기 때문입니다. 이 도구 모음은 Realtime Database, Cloud Storage, Pub/Sub, 인증, HTTP 호출 가능 트리거도 지원합니다. Remote Config 및 TestLab 트리거와 같은 다른 유형의 백그라운드 트리거는 이 페이지에 설명되지 않은 도구 모음을 사용하여 대화형으로 테스트할 수 있습니다.
이 가이드의 다음 섹션에서는 샘플을 빌드, 테스트, 배포하는 데 필요한 단계를 자세히 설명합니다.
Firebase 프로젝트 만들기
-
Firebase Console에서 프로젝트 추가를 클릭합니다.
-
기존 Google Cloud 프로젝트에 Firebase 리소스를 추가하려면 프로젝트 이름을 입력하거나 드롭다운 메뉴에서 선택합니다.
-
새 프로젝트를 만들려면 원하는 프로젝트 이름을 입력합니다. 필요한 경우 프로젝트 이름 아래에 표시되는 프로젝트 ID를 수정할 수도 있습니다.
-
-
메시지가 표시되면 Firebase 약관을 검토하고 이에 동의합니다.
-
계속을 클릭합니다.
-
(선택사항) 다음 Firebase 제품의 사용 환경을 최적화하려면 프로젝트에 Google Analytics를 설정합니다.
기존 Google Analytics 계정을 선택하거나 새 계정을 만듭니다.
새 계정을 만드는 경우 Analytics 보고 위치를 선택한 후 프로젝트의 데이터 공유 설정 및 Google Analytics 약관에 동의합니다.
-
프로젝트 만들기를 클릭합니다. 기존 Google Cloud 프로젝트를 사용하는 경우에는 Firebase 추가를 클릭합니다.
Firebase에서 Firebase 프로젝트용 리소스를 자동으로 프로비저닝합니다. 프로세스가 완료되면 Firebase Console에서 Firebase 프로젝트의 개요 페이지로 이동됩니다.
환경 및 Firebase CLI 설정
Node.js
함수를 작성하려면 Node.js 환경이 필요하고, 함수를 Cloud Functions 런타임에 배포하려면 Firebase CLI가 필요합니다. 노드 버전 관리자를 사용하여 Node.js와 npm을 설치하는 것이 좋습니다.
Node.js와 npm이 설치되었으면 원하는 방법으로 Firebase CLI를 설치합니다. npm을 통해 CLI를 설치하려면 다음을 사용하세요.
npm install -g firebase-tools
이렇게 하면 Firebase 전역 명령어가 설치됩니다. 명령어가 작동하지 않으면 npm 권한을 변경해야 할 수도 있습니다.
firebase-tools
의 최신 버전으로 업데이트하려면 같은 명령어를 다시 실행합니다.
Python
함수를 작성하려면 Python 환경이 필요하고, 함수를 Cloud Functions 런타임에 배포하려면 Firebase CLI가 필요합니다. venv
를 사용하여 종속 항목을 격리하는 것이 좋습니다. Python 버전 3.10 및 3.11이 지원됩니다.
Python이 설치되었으면 원하는 방법으로 Firebase CLI를 설치합니다.
프로젝트 초기화
Cloud Functions용 Firebase SDK를 초기화하려면 종속 항목과 일부 최소 샘플 코드가 포함된 빈 프로젝트를 만듭니다. Node.js를 사용하는 경우 함수 작성을 위해 TypeScript 또는 JavaScript 중 하나를 선택합니다. 이 튜토리얼에서는 Cloud Firestore도 초기화해야 합니다.
프로젝트를 초기화하는 방법은 다음과 같습니다.
firebase login
을 실행하여 브라우저를 통해 로그인하고 Firebase CLI를 인증합니다.- Firebase 프로젝트 디렉터리로 이동합니다.
firebase init firestore
를 실행합니다. 이 튜토리얼에서는 Firestore 규칙 및 색인 파일을 입력하라는 메시지가 표시되면 기본값을 사용할 수 있습니다. 이 프로젝트에서 아직 Cloud Firestore를 사용하지 않았다면 Cloud Firestore 시작하기에 설명된 대로 Firestore의 시작 모드와 위치도 선택해야 합니다.firebase init functions
를 실행합니다. CLI에 기존 코드베이스를 선택하거나 새 코드베이스를 초기화하고 이름을 지정하라는 메시지가 표시됩니다. 시작한 지 얼마 되지 않았으면 기본 위치의 단일 코드베이스로 충분합니다. 나중에 구현이 확장됨에 따라 코드베이스에서 함수를 구성할 수 있습니다.CLI는 다음 언어 지원 옵션을 제공합니다.
- JavaScript
- TypeScript
- Python
이 튜토리얼에서는 JavaScript 또는 Python을 선택합니다. TypeScript로 작성하는 방법은 TypeScript로 함수 작성을 참고하세요.
CLI를 사용하면 종속 항목을 설치할 수 있습니다. 종속 항목을 다른 방법으로 관리하려면 거부해도 됩니다.
이 명령어가 완료되면 프로젝트 구조는 다음과 같습니다.
Node.js
myproject
+- .firebaserc # Hidden file that helps you quickly switch between
| # projects with `firebase use`
|
+- firebase.json # Describes properties for your project
|
+- functions/ # Directory containing all your functions code
|
+- .eslintrc.json # Optional file containing rules for JavaScript linting.
|
+- package.json # npm package file describing your Cloud Functions code
|
+- index.js # Main source file for your Cloud Functions code
|
+- node_modules/ # Directory where your dependencies (declared in
# package.json) are installed
Node.js의 경우 초기화 중에 생성된 package.json
파일에는 중요한 키인 "engines": {"node": "18"}
이 포함되어 있습니다. 이 키는 함수 작성 및 배포를 위한 Node.js 버전을 의미합니다. 지원되는 다른 버전을 선택할 수 있습니다.
Python
myproject
+- .firebaserc # Hidden file that helps you quickly switch between
| # projects with `firebase use`
|
+- firebase.json # Describes properties for your project
|
+- functions/ # Directory containing all your functions code
|
+- main.py # Main source file for your Cloud Functions code
|
+- requirements.txt # List of the project's modules and packages
|
+- venv/ # Directory where your dependencies are installed
필수 모듈 가져오기 및 앱 초기화
설정 작업을 완료했으면 소스 디렉터리를 열고 다음 섹션에 설명된 대로 코드를 추가할 수 있습니다. 이 샘플의 경우 프로젝트에서 Cloud Functions 및 Admin SDK 모듈을 가져와야 합니다. 소스 파일에 다음 줄을 추가합니다.
Node.js
// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");
initializeApp();
Python
# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn
# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore
app = initialize_app()
이 줄은 필수 모듈을 로드하고 Cloud Firestore 변경이 가능한 admin
앱 인스턴스를 초기화합니다.
FCM, Authentication, Firebase Realtime Database처럼 Admin SDK가 지원되기만 하면 어디에서든 Cloud Functions를 사용하여 Firebase를 강력하게 통합할 수 있습니다.
프로젝트를 초기화하면 Firebase CLI가 자동으로 Cloud Functions 모듈용 Firebase Admin SDK 및 Firebase SDK를 설치합니다. 프로젝트에 서드 파티 라이브러리를 추가하는 방법에 관한 자세한 내용은 종속 항목 처리를 참고하세요.
'add message' 함수 추가
'add message' 함수의 경우 소스 파일에 다음 줄을 추가합니다.
Node.js
// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
// Grab the text parameter.
const original = req.query.text;
// Push the new message into Firestore using the Firebase Admin SDK.
const writeResult = await getFirestore()
.collection("messages")
.add({original: original});
// Send back a message that we've successfully written the message
res.json({result: `Message with ID: ${writeResult.id} added.`});
});
Python
@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
"""Take the text parameter passed to this HTTP endpoint and insert it into
a new document in the messages collection."""
# Grab the text parameter.
original = req.args.get("text")
if original is None:
return https_fn.Response("No text parameter provided", status=400)
firestore_client: google.cloud.firestore.Client = firestore.client()
# Push the new message into Cloud Firestore using the Firebase Admin SDK.
_, doc_ref = firestore_client.collection("messages").add({"original": original})
# Send back a message that we've successfully written the message
return https_fn.Response(f"Message with ID {doc_ref.id} added.")
'add message' 함수는 HTTP 엔드포인트입니다. 엔드포인트에 요청하면 요청 및 응답 객체가 플랫폼의 요청 핸들러에 전달됩니다(onRequest()
또는 on_request
).
HTTP 함수는 동기 함수이므로(호출 가능한 함수와 유사) 가능한 한 신속하게 응답을 보내고 Cloud Firestore를 사용하여 작업을 연기해야 합니다. 'add message' HTTP 함수는 텍스트 값을 HTTP 엔드포인트로 전달하고 /messages/:documentId/original
경로 아래의 데이터베이스에 삽입합니다.
'make uppercase' 함수 추가
'make uppercase' 함수의 경우 소스 파일에 다음 줄을 추가합니다.
Node.js
// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
// Grab the current value of what was written to Firestore.
const original = event.data.data().original;
// Access the parameter `{documentId}` with `event.params`
logger.log("Uppercasing", event.params.documentId, original);
const uppercase = original.toUpperCase();
// You must return a Promise when performing
// asynchronous tasks inside a function
// such as writing to Firestore.
// Setting an 'uppercase' field in Firestore document returns a Promise.
return event.data.ref.set({uppercase}, {merge: true});
});
Python
@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
"""Listens for new documents to be added to /messages. If the document has
an "original" field, creates an "uppercase" field containg the contents of
"original" in upper case."""
# Get the value of "original" if it exists.
if event.data is None:
return
try:
original = event.data.get("original")
except KeyError:
# No "original" field, so do nothing.
return
# Set the "uppercase" field.
print(f"Uppercasing {event.params['pushId']}: {original}")
upper = original.upper()
event.data.reference.update({"uppercase": upper})
'make uppercase' 함수는 Cloud Firestore이 작성될 때 실행되며 리슨할 문서를 정의합니다. 성능을 높이려면 최대한 구체적으로 정의해야 합니다.
중괄호(예: {documentId}
) 안에는 콜백에서 일치하는 데이터를 노출하는 와일드 카드인 '매개변수'를 입력합니다. Cloud Firestore는 새 메시지가 추가될 때마다 콜백을 트리거합니다.
Node.js에서 Cloud Firestore 이벤트와 같은 이벤트 기반 함수는 비동기 함수입니다. 콜백 함수는 null
, 객체, Promise 중 하나를 반환해야 합니다.
아무것도 반환하지 않으면 오류가 표시되면서 함수가 타임아웃되고 재시도됩니다. 동기, 비동기, 프로미스를 참조하세요.
함수 실행 에뮬레이션
Firebase Local Emulator Suite을 사용하면 Firebase 프로젝트에 배포하는 대신 로컬 머신에서 앱을 빌드하고 테스트할 수 있습니다. 개발 중에 실시하는 로컬 테스트는 프로덕션 환경에서 비용이 발생할 수 있는 코딩 오류(예: 무한 루프)의 위험을 줄일 수 있는 등의 이유로 적극 권장됩니다.
함수를 에뮬레이션하려면 다음 안내를 따르세요.
firebase emulators:start
를 실행하고 Emulator Suite UI의 URL 출력을 확인합니다. 기본값은 localhost:4000이지만 머신의 다른 포트에서 호스팅될 수 있습니다. 브라우저에 해당 URL을 입력하여 Emulator Suite UI를 엽니다.HTTP 함수의 URL은
firebase emulators:start
명령어의 출력에서 확인합니다. 다음을 제외하면http://localhost:5001/MY_PROJECT/us-central1/addMessage
와 유사합니다.MY_PROJECT
는 프로젝트 ID로 바뀝니다.- 포트는 로컬 머신에 따라 다를 수 있습니다.
함수 URL 끝에 쿼리 문자열
?text=uppercaseme
를 추가합니다.http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme
와 같이 표시됩니다. 원하는 경우 'uppercaseme' 메시지를 커스텀 메시지로 변경할 수 있습니다.브라우저의 새 탭에서 URL을 열어 새 메시지를 만듭니다.
Emulator Suite UI에서 함수의 효과를 확인합니다.
로그 탭에 HTTP 함수가 성공적으로 실행되었음을 나타내는 새 로그가 표시됩니다.
i functions: Beginning execution of "addMessage"
i functions: Beginning execution of "makeUppercase"
Firestore 탭에 원본 메시지와 메시지의 대문자 버전이 포함된 문서가 표시됩니다. 원본 메시지가 'uppercaseme'인 경우 'UPPERCASEME'가 표시됩니다.
프로덕션 환경에 함수 배포
함수가 에뮬레이터에서 원하는 대로 작동하면 프로덕션 환경에서 함수의 배포, 테스트, 실행을 진행할 수 있습니다. 프로덕션에 배포하려면 프로젝트에서 Blaze 요금제를 사용해야 합니다. Cloud Functions 가격 책정을 참조하세요.
튜토리얼을 완료하려면 함수를 배포한 후 실행합니다.
다음 명령어를 실행하여 함수를 배포합니다.
firebase deploy --only functions
이 명령어를 실행하면 Firebase CLI가 HTTP 함수 엔드포인트의 URL을 출력합니다. 터미널에 다음과 같은 줄이 표시됩니다.
Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
URL에는 프로젝트 ID와 HTTP 함수의 리전이 포함됩니다. 지금은 이에 대해 신경 쓸 필요는 없지만 일부 프로덕션 HTTP 함수는 네트워크 지연 시간이 최소화되도록 위치를 지정해야 합니다.
'프로젝트에 대한 액세스를 승인할 수 없음'과 같은 액세스 오류가 발생하면 프로젝트 별칭 관리를 확인해 보세요.
CLI의 URL 출력을 사용하여 텍스트 쿼리 매개변수를 추가하고 브라우저에서 엽니다.
https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
함수가 실행되고 텍스트 문자열이 저장된 데이터베이스 위치의 Firebase Console로 브라우저가 리디렉션됩니다. 이 쓰기 이벤트는 문자열의 대문자 버전을 작성하는 'make uppercase' 함수를 트리거합니다.
함수를 배포하고 실행한 후 Google Cloud Console에서 로그를 확인할 수 있습니다. 개발 또는 프로덕션 단계에서 함수를 삭제해야 할 경우 Firebase CLI를 사용하세요.
프로덕션에서는 실행할 최소 및 최대 인스턴스 수를 설정하여 함수 성능을 최적화하고 비용을 관리할 수 있습니다. 이러한 런타임 옵션에 대한 자세한 내용은 확장 동작 제어를 참조하세요.
다음 단계
이 문서에서는 Cloud Functions용 함수 관리 방법과 Cloud Functions에서 지원하는 모든 이벤트 유형을 처리하는 방법을 알아봅니다.
Cloud Functions에 대해 자세히 알아보려면 다음을 수행할 수도 있습니다.
- Cloud Functions 사용 사례 읽어보기
- Cloud Functions codelab사용해 보기
- GitHub의 코드 샘플 검토 및 실행하기