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


Để bắt đầu với Cloud Functions, hãy thử làm theo 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à hoạt động thông qua việc tạo, kiểm tra, và triển khai hai chức năng có liên quan:

  • Thông báo "thêm thông báo" hàm hiển thị một URL chấp nhận giá trị văn bản và ghi giá trị đó lên Cloud Firestore.
  • "Tạo chữ viết hoa" hàm kích hoạt khi ghi và biến đổi trên Cloud Firestore 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/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})

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

Chúng tôi đã chọn các hàm được kích hoạt trong Cloud Firestore và HTTP cho lấy mẫu một phần vì các trình kích hoạt ở chế độ nền này có thể được thử nghiệm kỹ lưỡng thông qua Bộ mô phỏng cục bộ của Firebase. Bộ công cụ này cũng hỗ trợ Cơ sở dữ liệu theo thời gian thực, Cloud Storage, Các trình kích hoạt có thể gọi PubSub, Xác thực và HTTP. Các loại trình kích hoạt trong nền khác chẳng hạn như các trình kích hoạt Cấu hình từ xa và TestLab đã thử nghiệm theo cách tương tác bằng cách sử dụng các bộ công cụ chứ không phải được mô tả trong trang này.

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

Tạo một dự án Firebase

  1. Trong bảng điều khiển của Firebase, hãy nhấp vào Thêm dự án.

    • Để thêm tài nguyên Firebase vào một dự án Google Cloud hiện có, hãy nhập tên dự án hoặc chọn tên dự án từ trình đơn thả xuống.

    • Để tạo một dự án mới, hãy nhập tên dự án mà bạn muốn. Bạn cũng có thể tuỳ ý chỉnh sửa mã dự án xuất hiện bên dưới tên dự án.

  2. Nếu được nhắc, hãy xem xét và chấp nhận các điều khoản của Firebase.

  3. Nhấp vào Tiếp tục.

  4. (Không bắt buộc) Thiết lập Google Analytics cho dự án của bạn để có thể để có trải nghiệm tối ưu khi sử dụng bất kỳ sản phẩm Firebase nào sau đây:

    Chọn một Tài khoản Google Analytics hoặc tạo tài khoản mới.

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

  5. Nhấp vào Tạo dự án (hoặc Thêm Firebase, nếu bạn đang sử dụng dự án hiện có trên Google Cloud).

Firebase tự động cấp tài nguyên cho dự án Firebase của bạn. Thời gian quá trình hoàn tất, bạn sẽ được đưa đến trang tổng quan cho Firebase dự án trong bảng điều khiển của 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 các hàm, và bạn cần có Giao diện dòng lệnh (CLI) của Firebase để triển khai các hàm nhằm thời gian chạy Cloud Functions. Để cài đặt Node.js và npm, Trình quản lý phiên bản nút .

Sau khi bạn đã cài đặt Node.js và npm, cài đặt Firebase CLI thông qua phương thức ưa thích của bạ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 firebase-tools mới nhất, hãy chạy lại lệnh đó.

Python

Bạn cần một môi trường Python để viết hàm, và bạn cần có Giao diện dòng lệnh (CLI) của Firebase để triển khai các hàm nhằm thời gian chạy Cloud Functions. Bạn nên sử dụng venv để các phần phụ thuộc. Các phiên bản Python 3.10 và 3.11 là được hỗ trợ.

Sau khi cài đặt Python, cài đặt Firebase CLI thông qua phương thức ưa thích của bạn.

Khởi chạy dự án

Khi khởi chạy Firebase SDK cho Cloud Functions, bạn sẽ tạo một dự án trống có chứa các phần phụ thuộc và một số mã mẫu tối thiểu. Nếu bạn sử dụng Node.js, bạn có thể chọn TypeScript hoặc JavaScript để soạn các hàm. Theo mục đích của tài liệu này, bạn cũng sẽ 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 Giao diện dòng lệnh (CLI) của 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 khi được nhắc về các quy tắc và tệp chỉ mục trên Firestore. Nếu bạn chưa sử dụng Cloud Firestore trong dự án này, bạn cũng sẽ cần chọn chế độ và vị trí bắt đầu cho Firestore như được mô tả trong Bắt đầu sử dụng Cloud Firestore.
  4. Chạy firebase init functions. CLI nhắc bạn chọn một cơ sở mã hoặc khởi chạy và đặt tên cho một cơ sở mã mới. Khi bạn vừa mới bắt đầu, một cơ sở mã duy nhất ở vị trí mặc định là đủ; sau này, khi việc triển khai của bạn mở rộng, bạn có thể sắp xếp các hàm trong cơ sở mã.
  5. CLI cung cấp cho bạn các tuỳ chọn hỗ trợ ngôn ngữ sau đây:

    • JavaScript
    • TypeScript
    • Python

    Đối với hướng dẫn này, hãy chọn JavaScript hoặc Python. Đối với tác giả trong TypeScript, hãy xem nội dung Viết hàm bằng TypeScript.

  6. CLI cung cấp cho bạn tuỳ chọn để cài đặt các phần phụ thuộc. Đây là một trường hợp an toàn từ chối nếu bạn 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 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 thông tin quan trọng khoá: "engines": {"node": "18"}. Thao tác này chỉ định phiên bản Node.js cho viết và triển khai các hàm. Bạn có thể chọn các phiên bản được hỗ trợ khác.

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 thành các bước thiết lập, bạn có thể mở thư mục nguồn và bắt đầu thêm mã như được 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 Chức năng đám mây và các mô-đun SDK quản trị. Thêm đườ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/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()

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

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

Thêm thông báo "thêm thông báo" hàm

Đối với tuỳ chọn "thêm thông báo" hãy thêm các dòng sau vào tệp nguồn của bạ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.")

Lệnh "thêm thông báo" là một điểm cuối HTTP. Bất kỳ yêu cầu nào đến điểm cuối dẫn đến 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).

Các hàm HTTP có tính đồng bộ (tương tự như hàm có thể gọi), nên 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 cách sử dụng Cloud Firestore. Lệnh "thêm thông báo" Hàm HTTP 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 dòng chữ "viết hoa" hàm

Đối với yêu cầu "viết hoa" hãy thêm các dòng sau vào tệp nguồn của bạ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})

Cụm từ "viết hoa" hàm thực thi khi Cloud Firestore được ghi vào, xác định tài liệu cần nghe. Vì lý do hiệu suất, bạn phải 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 trùng khớp trong lệnh gọi lại. Cloud Firestore kích hoạt bất cứ khi nào có tin nhắn mới được thêm.

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

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

Chiến lược phát hành đĩa đơn Bộ mô phỏng cục bộ của Firebase cho phép bạn tạo và kiểm thử ứng dụng trên máy cục bộ thay vì triển khai cho 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 bởi công cụ này giúp giảm rủi ro do lỗi lập trình có thể xảy ra phải chịu chi phí trong môi trường sản xuất (ví dụ: vòng lặp vô hạn).

Cách mô phỏng các hàm của bạn:

  1. Chạy firebase emulators:start và kiểm tra kết quả cho URL của giao diện người dùng Bộ mô phỏng. Giá trị mặc định là localhost:4000, nhưng có thể được lưu trữ trên cổng trên máy của bạn. Nhập URL đó vào trình duyệt của bạn để mở Giao diện người dùng của Bộ mô phỏng.

  2. Kiểm tra kết quả của firebase emulators:start cho URL của hàm HTTP. Nút này sẽ trông giống như http://localhost:5001/MY_PROJECT/us-central1/addMessage, ngoại trừ:

    1. MY_PROJECT sẽ được thay thế bằng mã dự án của bạn.
    2. Cổng trên máy cục bộ có thể khác.
  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 "viết hoa" sang một thành phần tuỳ chỉnh .

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

  5. Xem hiệu ứng của các hàm trong giao diện người dùng của Bộ mô phỏng:

    1. Trong thẻ Logs (Nhật ký), bạn sẽ thấy các 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 nội dung gốc cũng như phiên bản viết hoa của thông báo (nếu có ban đầu là "chữ hoa", bạn sẽ thấy chữ "viết hoa".

Triển khai các chức năng trong môi trường sản xuất

Khi các hàm của bạn hoạt động như mong muốn trong trình mô phỏng, bạn có thể tiếp tục triển khai, thử nghiệm và chạy chúng trong môi trường sản xuất. Lưu ý để triển khai trong thực tế, dự án của bạn phải có trong Gói giá linh hoạt. 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 của bạn:

     firebase deploy --only functions
     

    Sau khi bạn chạy lệnh này, Firebase CLI sẽ xuất ra URL cho bất kỳ Hàm HTTP điểm cuối. 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 dành cho giao thức HTTP . Mặc dù hiện tại bạn không cần lo lắng về điều này, nhưng một số giao thức HTTP nên chỉ định location (vị trí) để giảm thiểu độ trễ mạng.

    Nếu bạn gặp phải lỗi truy cập như "Không thể cấp quyền truy cập vào dự án" hãy thử kiểm tra đặt bí danh dự án của bạn.

  2. Sử dụng URL do CLI xuất ra, thêm tham số truy vấn văn bản, và mở tệp đó 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 của Firebase tại vị trí cơ sở dữ liệu nơi chuỗi văn bản được lưu trữ. Chiến dịch này Sự kiện ghi sẽ kích hoạt lệnh "viết hoa" viết hoa phiên bản của chuỗi.

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

Trong phiên bản phát hành công khai, bạn nên tối ưu hoá khả năng kiểm soát và hiệu suất của chức năng bằng cách đặt số lượng thực thể tối thiểu và tối đa cần chạy. Xem 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ý chức năng dành cho Cloud Functions cũng như cách để xử lý tất cả các loại sự kiện được Cloud Functions hỗ trợ.

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