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 tác vụ thiết lập bắt buộc và hướng dẫn cách tạo, kiểm thử và triển khai hai hàm có liên quan:

  • Một hàm "add message" (thêm tin nhắn) hiển thị một URL chấp nhận giá trị văn bản và ghi giá trị đó vào Cloud Firestore.
  • Một hàm "chuyển thành chữ hoa" sẽ kích hoạt khi ghi Cloud Firestore và chuyển đổi văn bản thành chữ hoa.

Chúng tôi đã chọn Cloud Firestore và các hàm JavaScript được kích hoạt bằng HTTP cho mẫu này một phần vì bạn có thể kiểm thử kỹ lưỡng các trình kích hoạt ở chế độ nền này thông qua Firebase Local Emulator Suite. Bộ công cụ này cũng hỗ trợ Realtime Database, PubSub, Auth và các trình kích hoạt có thể gọi HTTP. Các loại điều kiện kích hoạt khác ở chế độ nền, chẳng hạn như Remote Config, TestLab và điều kiện kích hoạt Analytics đều có thể được kiểm thử một cách tương tác 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 đâ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, kiểm thử và triển khai mẫu. Nếu bạn chỉ muốn chạy mã và kiểm tra mã đó, hãy chuyển đến phần Xem xét mã mẫu hoàn chỉnh.

Tạo dự án Firebase

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

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

    • Để tạo một dự án mới, hãy nhập tên dự á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. Việc này giúp mang lại trải nghiệm tối ưu khi sử dụng các sản phẩm sau đây của Firebase: Firebase A/B Testing, Cloud Messaging, Crashlytics, In-App MessagingRemote Config (bao gồm cả 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 Analyticsvị trí báo cáo, sau đó chấp nhận chế độ chia sẻ dữ liệu và Google Analyticsđiều khoản 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 thêm Firebase vào một dự án Google Cloud hiện có).

Firebase tự động cung cấp tài nguyên cho dự án Firebase 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 về dự án Firebase của mình trong bảng điều khiển Firebase.

Thiết lập Node.js và Giao diện dòng lệnh (CLI) của Firebase

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

Sau khi bạn cài đặt Node.js và npm, hãy cài đặt Firebase CLI bằng phương thức bạn muốn. Để cài đặt CLI thông 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ực hiện được, bạn có thể phải 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 tương tự.

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, đồng thời bạn có thể chọn TypeScript hoặc JavaScript để tạo các hàm. Để phục vụ mục đích của hướng dẫn này, bạn cũng cần khởi động 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. Trong 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ề các quy tắc và tệp chỉ mục của Firestore. Nếu chưa dùng Cloud Firestore trong dự án này, bạn cũng cần chọn chế độ và vị trí bắt đầu 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 cơ sở mã hiện có hoặc khởi động và đặt tên cho một cơ sở mã mới. Khi mới bắt đầu, một cơ sở mã duy nhất ở vị trí mặc định là đủ; sau đó, khi quá trình triển khai của bạn mở rộng, bạn có thể muốn sắp xếp các hàm trong cơ sở mã.

  5. CLI cung cấp cho bạn các lựa chọn sau đây để hỗ trợ ngôn ngữ:

    Đối với hướng dẫn này, hãy chọn JavaScript.

  6. CLI cho phép bạn cài đặt các phần phụ thuộc bằng npm. Bạn có thể từ chối nếu muốn quản lý các phần phụ thuộc theo cách khác. Tuy nhiên, nếu từ chối, bạn sẽ cần chạy npm install trước khi mô phỏng hoặc triển khai các hàm.

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:

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

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": "16"}. Thao tác này chỉ định phiên bản Node.js để 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.

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

Sau khi hoàn tất các tác 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à Admin SDK bằng cách sử dụng các câu lệnh require của Node. Thêm các dòng như sau vào tệp index.js:

// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions/v1');

// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
admin.initializeApp();

Các dòng này tải các mô-đun firebase-functionsfirebase-admin, đồng thời khởi tạo 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ó dịch vụ hỗ trợ Admin SDK, chẳng hạn như đối với FCM, AuthenticationFirebase Realtime Database, dịch vụ này đều cung cấp một cách hiệu quả để tích hợp Firebase bằng Cloud Functions.

CLI Firebase sẽ tự động cài đặt SDK Firebase và Firebase cho các mô-đun Cloud Functions Node khi bạn khởi chạy dự án. Để thêm thư viện của bên thứ ba vào dự án, bạn có thể sửa đổi package.json và chạy npm install. Để biết thêm thông tin, hãy xem bài viết Xử lý các phần phụ thuộc.

Thêm hàm addMessage()

Đối với hàm addMessage(), hãy thêm các dòng sau vào index.js:

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.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 admin
    .firestore()
    .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.` });
});

Hàm addMessage() là một điểm cuối HTTP. Mọi yêu cầu đến điểm cuối đều dẫn đến các đối tượng RequestResponse theo kiểu ExpressJS được truyền đến lệnh gọi lại onRequest().

Các hàm HTTP là đồng bộ (tương tự như các 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 cách sử dụng Cloud Firestore. Hàm addMessage() 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 hàm makeUppercase()

Đối với hàm makeUppercase(), hãy thêm các dòng sau vào index.js:

// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore
  .document("/messages/{documentId}")
  .onCreate((snap, context) => {
    // Grab the current value of what was written to Firestore.
    const original = snap.data().original;

    // Access the parameter `{documentId}` with `context.params`
    functions.logger.log("Uppercasing", context.params.documentId, original);

    const uppercase = original.toUpperCase();

    // You must return a Promise when performing asynchronous tasks inside a Functions such as
    // writing to Firestore.
    // Setting an 'uppercase' field in Firestore document returns a Promise.
    return snap.ref.set({ uppercase }, { merge: true });
  });

Hàm makeUppercase() sẽ thực thi khi Cloud Firestore được ghi vào. Hàm ref.set xác định tài liệu cần theo dõi. Vì lý do hiệu suất, bạn nên nêu cụ thể nhất có thể.

Dấu ngoặc nhọn (ví dụ: {documentId}) bao quanh "các tham số", ký tự đại diện hiển thị dữ liệu được so khớp trong lệnh gọi lại.

Cloud Firestore sẽ kích hoạt lệnh gọi lại onCreate() bất cứ khi nào có tin nhắn mới được thêm.

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

Mô phỏng việc thực thi các hàm

Firebase Local Emulator Suite 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 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 là vì việc này giúp giảm nguy cơ do lỗi lập trình có thể phát sinh 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:

  1. Chạy firebase emulators:start và kiểm tra đầu ra để tìm URL của Emulator Suite UI. Theo mặc định, giá trị 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 đầu ra của lệnh firebase emulators:start để biết URL của hàm HTTP addMessage(). Mã này sẽ có dạng tương tự 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 này 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. Đoạn 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ư mới bằng cách mở URL trong một 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 các hàm addMessage()makeUppercase() đã chạy:

      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 sản xuấ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 sản xuất. Xin lưu ý rằng để triển khai vào môi trường thời gian chạy Node.js 14, dự án của bạn phải sử dụng Gói giá linh hoạt. Xem Cloud Functions giá.

Để hoàn tất hướng dẫn này, hãy triển khai các hàm của bạn rồi thực thi addMessage() để kích hoạt makeUppercase().

  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, CLI Firebase sẽ xuất URL cho mọi điểm cuối của hàm HTTP. Trong cửa sổ 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ủa bạn cũng như một khu vực cho hàm HTTP. Mặc dù hiện tại bạn không cần lo lắng về vấn đề này, nhưng một số hàm HTTP sản xuất phải chỉ định một vị trí để giảm thiểu độ trễ mạng.

    Nếu bạn gặp 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 bí danh dự án.

  2. Sử dụng đầu ra URL addMessage() do CLI tạo, thêm một 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 chuỗi văn bản được lưu trữ. Sự kiện ghi này sẽ kích hoạt makeUppercase(), 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 sản xuất, hãy dùng CLI Firebase.

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

Xem lại mã mẫu hoàn chỉnh

Sau đây là functions/index.js hoàn chỉnh chứa các hàm addMessage()makeUppercase(). Các hàm này cho phép bạn truyền một tham số đến một điểm cuối HTTP ghi giá trị vào Cloud Firestore, sau đó chuyển đổi giá trị đó bằng cách viết hoa tất cả các ký tự trong chuỗi.

// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions/v1');

// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
admin.initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.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 admin
    .firestore()
    .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 creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore
  .document("/messages/{documentId}")
  .onCreate((snap, context) => {
    // Grab the current value of what was written to Firestore.
    const original = snap.data().original;

    // Access the parameter `{documentId}` with `context.params`
    functions.logger.log("Uppercasing", context.params.documentId, original);

    const uppercase = original.toUpperCase();

    // You must return a Promise when performing asynchronous tasks inside a Functions such as
    // writing to Firestore.
    // Setting an 'uppercase' field in Firestore document returns a Promise.
    return snap.ref.set({ uppercase }, { merge: true });
  });

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ý các 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: