Bắt đầu: viết, kiểm thử và triển khai các hàm đầu tiên

Để bắt đầu sử dụng Cloud Functions, hãy thử làm theo hướng dẫn này. Hướng dẫn này bắt đầu bằng các nhiệm vụ thiết lập bắt buộc và thực hiện việc tạo, kiểm thử cũng như triển khai hai hàm có liên quan:

  • Hàm "add message" (thêm thông báo) hiển thị một URL chấp nhận giá trị văn bản và ghi giá trị đó vào Cloud Firestore.
  • Hàm "viết hoa" kích hoạt khi có thao tác ghi Cloud Firestore và chuyển đổi văn bản thành chữ hoa.

Dưới đây là mã mẫu đầy đủ chứa các hàm:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/https");
const {onDocumentCreated} = require("firebase-functions/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})

Giới thiệu về hướng dẫn này

Chúng tôi đã chọn Cloud Firestore và các hàm được kích hoạt bằng HTTP cho mẫu này một phần vì các điều kiện kích hoạt trong nền này có thể được kiểm thử kỹ lưỡng thông qua Firebase Local Emulator Suite. Bộ công cụ này cũng hỗ trợ Realtime Database, Cloud Storage, PubSub, Auth và trình kích hoạt có thể gọi HTTP. Bạn có thể kiểm thử tương tác các loại trình kích hoạt nền khác như trình kích hoạt Remote Config và TestLab bằng cách sử dụng các bộ công cụ không được mô tả trên trang này.

Các phần sau của hướng dẫn này trình bày chi tiết các bước cần thiết để xây dựng, kiểm thử và triển khai mẫu.

Tạo dự án Firebase

Bạn mới sử dụng Firebase hoặc Cloud?

Làm theo các bước sau nếu bạn mới sử dụng Firebase hoặc Google Cloud.
Bạn cũng có thể làm theo các bước này nếu muốn tạo một dự án Firebase hoàn toàn mới (và dự án Google Cloud cơ bản của dự án đó).

  1. Đăng nhập vào bảng điều khiển Firebase.
  2. Nhấp vào nút này để tạo một dự án Firebase mới.
  3. Trong trường văn bản, hãy nhập tên dự án.

    Nếu thuộc một tổ chức Google Cloud, bạn có thể tuỳ ý chọn thư mục để tạo dự án.

  4. Nếu được nhắc, hãy xem và chấp nhận điều khoản của Firebase, sau đó nhấp vào Tiếp tục.
  5. (Không bắt buộc) Bật tính năng trợ giúp AI trong bảng điều khiển Firebase (gọi là "Gemini trong Firebase"). Tính năng này có thể giúp bạn bắt đầu và đơn giản hoá quy trình phát triển.
  6. (Không bắt buộc) Thiết lập Google Analytics cho dự án của bạn để có trải nghiệm tối ưu khi sử dụng các sản phẩm Firebase sau: Firebase A/B Testing, Cloud Messaging, Crashlytics, In-App Messaging và Remote Config (bao gồm cả tính năng Cá nhân hoá).

    Chọn một tài khoản Google Analytics hiện có hoặc tạo một tài khoản mới. Nếu bạn tạo tài khoản mới, hãy chọn Analytics vị trí báo cáo, sau đó chấp nhận chế độ cài đặt cách chia sẻ dữ liệu và Google Analytics điều khoản cho dự án của bạn.

  7. Nhấp vào Tạo dự án.

Firebase sẽ tạo dự án, cung cấp một số tài nguyên ban đầu và bật các API quan trọng. Khi quá trình này hoàn tất, bạn sẽ được chuyển đến trang tổng quan cho dự án Firebase của mình trong bảng điều khiển Firebase.

Dự án hiện có trên đám mây

Hãy làm theo các bước sau nếu bạn muốn bắt đầu sử dụng Firebase với một dự án Google Cloud hiện có. Tìm hiểu thêm và khắc phục sự cố "thêm Firebase" vào một dự án Google Cloud hiện có.

  1. Đăng nhập vào bảng điều khiển Firebase bằng tài khoản cấp cho bạn quyền truy cập vào dự án Google Cloud hiện có.
  2. Nhấp vào nút này để tạo một dự án Firebase mới.
  3. Ở cuối trang, hãy nhấp vào Thêm Firebase vào dự án Google Cloud.
  4. Trong trường văn bản, hãy bắt đầu nhập tên dự án của dự án hiện có, sau đó chọn dự án trong danh sách hiển thị.
  5. Nhấp vào Mở dự án.
  6. Nếu được nhắc, hãy xem và chấp nhận điều khoản của Firebase, sau đó nhấp vào Tiếp tục.
  7. (Không bắt buộc) Bật tính năng trợ giúp AI trong bảng điều khiển Firebase (gọi là "Gemini trong Firebase"). Tính năng này có thể giúp bạn bắt đầu và đơn giản hoá quy trình phát triển.
  8. (Không bắt buộc) Thiết lập Google Analytics cho dự án của bạn để có trải nghiệm tối ưu khi sử dụng các sản phẩm Firebase sau: Firebase A/B Testing, Cloud Messaging, Crashlytics, In-App Messaging và Remote Config (bao gồm cả tính năng Cá nhân hoá).

    Chọn một tài khoản Google Analytics hiện có hoặc tạo một tài khoản mới. Nếu bạn tạo tài khoản mới, hãy chọn Analytics vị trí báo cáo, sau đó chấp nhận chế độ cài đặt cách chia sẻ dữ liệu và Google Analytics điều khoản cho dự án của bạn.

  9. Nhấp vào Thêm Firebase.

Firebase sẽ thêm Firebase vào dự án hiện có của bạn. Khi quá trình này hoàn tất, bạn sẽ được chuyển đến trang tổng quan cho dự án Firebase của mình trong bảng điều khiển Firebase.

Thiết lập môi trường và Giao diện dòng lệnh (CLI) của Firebase

Node.js

Bạn cần có môi trường Node.js để viết hàm và cần có CLI Firebase để triển khai hàm cho thời gian chạy Cloud Functions. Bạn nên dùng Trình quản lý phiên bản nút để cài đặt Node.js và npm.

Sau khi cài đặt Node.js và npm, hãy cài đặt Firebase CLI thông qua phương thức bạn muốn. Để cài đặt CLI qua npm, hãy sử dụng:

npm install -g firebase-tools

Thao tác này sẽ cài đặt lệnh firebase có sẵn trên toàn cầu. Nếu lệnh không thành công, bạn có thể cần thay đổi quyền npm. Để cập nhật lên phiên bản mới nhất của firebase-tools, hãy chạy lại lệnh đó.

Python

Bạn cần có môi trường Python để viết hàm và cần có CLI Firebase để triển khai hàm cho môi trường thời gian chạy Cloud Functions. Bạn nên sử dụng venv để tách biệt các phần phụ thuộc. Các phiên bản Python từ 3.10 đến 3.13 đều được hỗ trợ, trong đó 3.13 là môi trường thời gian chạy mặc định.

Sau khi cài đặt Python, hãy cài đặt Firebase CLI thông qua phương thức bạn muốn.

Khởi chạy dự án

Khi khởi chạy SDK Firebase cho Cloud Functions, bạn sẽ tạo một dự án trống chứa các phần phụ thuộc và một số mã mẫu tối thiểu. Nếu đang sử dụng Node.js, bạn có thể chọn TypeScript hoặc JavaScript để soạn hàm. Để thực hiện hướng dẫn này, bạn cũng cần khởi chạy Cloud Firestore.

Cách khởi chạy dự án:

  1. Chạy firebase login để đăng nhập qua trình duyệt và xác thực CLI Firebase.
  2. Chuyển đến thư mục dự án Firebase của bạn.
  3. Chạy firebase init firestore. Đối với hướng dẫn này, bạn có thể chấp nhận các giá trị mặc định khi được nhắc về quy tắc và tệp chỉ mục của Firestore. Nếu chưa từng sử dụng Cloud Firestore trong dự án này, bạn cũng cần chọn chế độ bắt đầu và vị trí cho Firestore như mô tả trong phần Bắt đầu sử dụng Cloud Firestore.
  4. Chạy firebase init functions. CLI sẽ nhắc bạn chọn một toàn bộ mã nguồn hiện có hoặc khởi động và đặt tên cho một toàn bộ mã nguồn mới. Khi mới bắt đầu, một toàn bộ mã nguồn duy nhất ở vị trí mặc định là đủ; sau này, khi quá trình triển khai mở rộng, bạn có thể muốn sắp xếp các Functions trong toàn bộ mã nguồn.
  5. CLI cung cấp cho bạn các lựa chọn sau để hỗ trợ ngôn ngữ:

    • JavaScript
    • TypeScript
    • Python

    Đối với hướng dẫn này, hãy chọn JavaScript hoặc Python. Để biết cách tạo bằng TypeScript, hãy xem bài viết Viết hàm bằng TypeScript.

  6. CLI cung cấp cho bạn một tuỳ chọn để cài đặt các phần phụ thuộc. Bạn có thể từ chối một cách an toàn nếu muốn quản lý các phần phụ thuộc theo cách khác.

Sau khi các lệnh này hoàn tất thành công, cấu trúc dự án của bạn sẽ có dạng như sau:

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

Đối với Node.js, tệp package.json được tạo trong quá trình khởi chạy chứa một khoá quan trọng: "engines": {"node": "18"}. Thông tin này chỉ định phiên bản Node.js của bạn để viết và triển khai các hàm. Bạn có thể chọn các phiên bản khác được hỗ trợ.

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

Nhập các mô-đun bắt buộc và khởi chạy ứng dụng

Sau khi hoàn tất các nhiệm vụ thiết lập, bạn có thể mở thư mục nguồn và bắt đầu thêm mã như mô tả trong các phần sau. Đối với mẫu này, dự án của bạn phải nhập các mô-đun Cloud Functions và SDK dành cho quản trị viên. Thêm các dòng như sau vào tệp nguồn:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/https");
const {onDocumentCreated} = require("firebase-functions/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()

Các dòng này tải các mô-đun bắt buộc và khởi động một thực thể ứng dụng admin mà từ đó có thể thực hiện các thay đổi Cloud Firestore. Bất cứ nơi nào có hỗ trợ SDK dành cho quản trị viên, như đối với FCM, Authentication và Firebase Realtime Database, thì SDK này sẽ cung cấp một cách hiệu quả để tích hợp Firebase bằng Cloud Functions.

Giao diện dòng lệnh (CLI) của Firebase sẽ tự động cài đặt SDK quản trị Firebase và SDK Firebase cho các mô-đun Cloud Functions khi bạn khởi chạy dự án. Để biết thêm thông tin về cách thêm thư viện bên thứ ba vào dự án, hãy xem phần Xử lý phần phụ thuộc.

Thêm hàm "add message" (thêm thông báo)

Đối với hàm "add message" (thêm thông báo), hãy thêm các dòng sau vào tệp nguồn:

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.")

Hàm "add message" (thêm thông báo) là một điểm cuối HTTP. Mọi yêu cầu đến điểm cuối đều dẫn đến việc các đối tượng yêu cầu và phản hồi được chuyển đến trình xử lý yêu cầu cho nền tảng của bạn (onRequest() hoặc on_request).

Hàm HTTP là hàm đồng bộ (tương tự như hàm có thể gọi), vì vậy, bạn nên gửi phản hồi nhanh nhất có thể và trì hoãn công việc bằng Cloud Firestore. Hàm HTTP "add message" (thêm thông báo) truyền một giá trị văn bản đến điểm cuối HTTP và chèn giá trị đó vào cơ sở dữ liệu theo đường dẫn /messages/:documentId/original.

Thêm hàm "make uppercase" (viết hoa)

Đối với hàm "make uppercase", hãy thêm các dòng sau vào tệp nguồn:

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})

Hàm "make uppercase" (viết hoa) thực thi khi Cloud Firestore được ghi vào, xác định tài liệu cần theo dõi. Để đảm bảo hiệu suất, bạn nên chỉ định càng cụ thể càng tốt.

Dấu ngoặc nhọn (ví dụ: {documentId}) bao quanh "tham số", ký tự đại diện hiển thị dữ liệu khớp của chúng trong lệnh gọi lại. Cloud Firestore kích hoạt lệnh gọi lại bất cứ khi nào có tin nhắn mới được thêm vào.

Trong Node.js, các hàm dựa trên sự kiện như sự kiện Cloud Firestore là không đồng bộ. Hàm callback phải trả về một null, một Đối tượng hoặc một Promise. Nếu bạn không trả về kết quả nào, hàm sẽ hết thời gian chờ, báo lỗi và thử lại. Xem phần Đồng bộ, không đồng bộ và lời hứa.

Mô phỏng quá trình thực thi các hàm

Firebase Local Emulator Suite cho phép bạn xây dựng và kiểm thử ứng dụng trên máy cục bộ thay vì triển khai cho một dự án Firebase. Bạn nên kiểm thử cục bộ trong quá trình phát triển, một phần vì việc này giúp giảm rủi ro do lỗi lập trình có thể gây tốn kém trong môi trường thực tế (ví dụ: vòng lặp vô hạn).

Cách mô phỏng các hàm:

  1. Chạy firebase emulators:start và kiểm tra kết quả cho URL của Emulator Suite UI. Theo mặc định, URL này là localhost:4000, nhưng có thể được lưu trữ trên một cổng khác trên máy của bạn. Nhập URL đó vào trình duyệt để mở Emulator Suite UI.

  2. Kiểm tra kết quả của lệnh firebase emulators:start để tìm URL của hàm HTTP. Nó sẽ có dạng tương tự như http://localhost:5001/MY_PROJECT/us-central1/addMessage, ngoại trừ việc:

    1. MY_PROJECT sẽ được thay thế bằng mã dự án của bạn.
    2. Cổng có thể khác trên máy cục bộ của bạn.
  3. Thêm chuỗi truy vấn ?text=uppercaseme vào cuối URL của hàm. Mã này sẽ có dạng như sau: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme. Nếu muốn, bạn có thể thay đổi thông báo "uppercaseme" thành một thông báo tuỳ chỉnh.

  4. Tạo thông báo mới bằng cách mở URL trong thẻ mới trên trình duyệt.

  5. Xem hiệu ứng của các hàm trong Emulator Suite UI:

    1. Trong thẻ Nhật ký, bạn sẽ thấy nhật ký mới cho biết rằng các hàm HTTP của bạn đã chạy thành công:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. Trong thẻ Firestore, bạn sẽ thấy một tài liệu chứa thông báo ban đầu cũng như phiên bản viết hoa của thông báo (nếu ban đầu là "uppercaseme", bạn sẽ thấy "UPPERCASEME").

Triển khai các hàm vào môi trường thực tế

Sau khi các hàm hoạt động như mong muốn trong trình mô phỏng, bạn có thể tiến hành triển khai, kiểm thử và chạy các hàm đó trong môi trường thực tế. Xin lưu ý rằng để triển khai trong môi trường thực tế, dự án của bạn phải sử dụng gói giá Blaze. Xem giá của Cloud Functions.

Để hoàn tất hướng dẫn, hãy triển khai các hàm rồi thực thi chúng.

  1. Chạy lệnh này để triển khai các hàm:

     firebase deploy --only functions
     

    Sau khi bạn chạy lệnh này, CLI Firebase sẽ xuất URL cho mọi điểm cuối của hàm HTTP. Trong dòng lệnh, bạn sẽ thấy một dòng như sau:

    Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
    

    URL này chứa mã dự án cũng như khu vực cho hàm HTTP. Mặc dù bạn không cần lo lắng về vấn đề này, nhưng một số hàm HTTP chính thức nên chỉ định một vị trí để giảm thiểu độ trễ mạng.

    Nếu bạn gặp lỗi truy cập, chẳng hạn như "Không thể uỷ quyền truy cập vào dự án", hãy thử kiểm tra bí danh dự án.

  2. Sử dụng URL do CLI xuất ra, thêm tham số truy vấn văn bản và mở tham số đó trong trình duyệt:

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
    

    Hàm này thực thi và chuyển hướng trình duyệt đến bảng điều khiển Firebase tại vị trí cơ sở dữ liệu nơi lưu trữ chuỗi văn bản. Sự kiện ghi này kích hoạt hàm "make uppercase" (viết hoa), hàm này sẽ ghi phiên bản viết hoa của chuỗi.

Sau khi triển khai và thực thi các hàm, bạn có thể xem nhật ký trong bảng điều khiển Google Cloud. Nếu bạn cần xoá các hàm trong quá trình phát triển hoặc phát hành công khai, hãy sử dụng CLI Firebase.

Trong môi trường thực tế, bạn nên tối ưu hoá hiệu suất của hàm và kiểm soát chi phí bằng cách đặt số lượng thực thể tối thiểu và tối đa để chạy. Hãy xem phần Kiểm soát hành vi điều chỉnh tỷ lệ để biết thêm thông tin về các tuỳ chọn thời gian chạy này.

Các bước tiếp theo

Trong tài liệu này, bạn có thể tìm hiểu thêm về cách quản lý hàm cho Cloud Functions cũng như cách xử lý tất cả các loại sự kiện mà Cloud Functions hỗ trợ.

Để tìm hiểu thêm về Cloud Functions, bạn cũng có thể làm như sau: