Trang này hướng dẫn bạn các bước cần thiết để tạo một Tiện ích Firebase đơn giản. Bạn có thể cài đặt tiện ích này trong các dự án của mình hoặc chia sẻ với người khác. Ví dụ đơn giản này về Tiện ích Firebase sẽ theo dõi Cơ sở dữ liệu theo thời gian thực để tìm thông báo và chuyển đổi các thông báo đó thành chữ hoa.
1. Thiết lập môi trường và khởi chạy dự án
Trước khi có thể bắt đầu tạo một tiện ích, bạn cần thiết lập môi trường xây dựng bằng các công cụ bắt buộc.
Cài đặt Node.js 16 trở lên. Một cách để cài đặt Node là sử dụng nvm (hoặc nvm-windows).
Cài đặt hoặc cập nhật lên phiên bản mới nhất của Firebase CLI. Để cài đặt hoặc cập nhật bằng
npm
, hãy chạy lệnh sau:npm install -g firebase-tools
Bây giờ, hãy sử dụng Giao diện dòng lệnh (CLI) của Firebase để khởi chạy một dự án tiện ích mới:
Tạo thư mục cho tiện ích và
cd
vào thư mục đó:mkdir rtdb-uppercase-messages && cd rtdb-uppercase-messages
Chạy lệnh
ext:dev:init
của Firebase CLI:firebase ext:dev:init
Khi được nhắc, hãy chọn JavaScript làm ngôn ngữ cho các hàm (nhưng lưu ý rằng bạn cũng có thể sử dụng TypeScript khi phát triển tiện ích của riêng mình) và khi được yêu cầu cài đặt các phần phụ thuộc, hãy trả lời "có". (Chấp nhận các tuỳ chọn mặc định cho mọi tuỳ chọn khác.) Lệnh này sẽ thiết lập cơ sở mã khung cho một tiện ích mới, từ đó bạn có thể bắt đầu phát triển tiện ích của mình.
2. Dùng thử tiện ích mẫu bằng trình mô phỏng
Khi khởi chạy thư mục tiện ích mới, Firebase CLI đã tạo một hàm ví dụ đơn giản và thư mục integration-tests
chứa các tệp cần thiết để chạy tiện ích bằng bộ trình mô phỏng Firebase.
Hãy thử chạy tiện ích mẫu trong trình mô phỏng:
Thay đổi thành thư mục
integration-tests
:cd functions/integration-tests
Khởi động trình mô phỏng bằng một dự án minh hoạ:
firebase emulators:start --project=demo-test
Trình mô phỏng tải tiện ích vào một dự án "giả" được xác định trước (
demo-test
). Cho đến nay, tiện ích này bao gồm một hàm duy nhất được kích hoạt bằng HTTP,greetTheWorld
, hàm này trả về thông báo "hello world" (xin chào thế giới) khi được truy cập.Khi trình mô phỏng vẫn đang chạy, hãy thử hàm
greetTheWorld
của tiện ích bằng cách truy cập URL được in khi bạn khởi động.Trình duyệt của bạn sẽ hiển thị thông báo "Hello World from greet-the-world" (Xin chào thế giới từ greet-the-world).
Mã nguồn của hàm này nằm trong thư mục
functions
của tiện ích. Mở nguồn trong trình chỉnh sửa hoặc IDE mà bạn chọn:functions/index.js
const functions = require("firebase-functions/v1"); exports.greetTheWorld = functions.https.onRequest((req, res) => { // Here we reference a user-provided parameter // (its value is provided by the user during installation) const consumerProvidedGreeting = process.env.GREETING; // And here we reference an auto-populated parameter // (its value is provided by Firebase after installation) const instanceId = process.env.EXT_INSTANCE_ID; const greeting = `${consumerProvidedGreeting} World from ${instanceId}`; res.send(greeting); });
Khi đang chạy, trình mô phỏng sẽ tự động tải lại mọi thay đổi mà bạn thực hiện đối với mã Hàm. Hãy thử thay đổi một chút hàm
greetTheWorld
:functions/index.js
const greeting = `${consumerProvidedGreeting} everyone, from ${instanceId}`;
Lưu thay đổi. Trình mô phỏng sẽ tải lại mã của bạn và giờ đây, khi truy cập vào URL của hàm, bạn sẽ thấy lời chào đã cập nhật.
3. Thêm thông tin cơ bản vào extension.yaml
Giờ đây, khi đã thiết lập môi trường phát triển và đang chạy trình mô phỏng tiện ích, bạn có thể bắt đầu viết tiện ích của riêng mình.
Một bước đầu tiên đơn giản là chỉnh sửa siêu dữ liệu của tiện ích được xác định trước để phản ánh tiện ích bạn muốn viết thay vì greet-the-world
. Siêu dữ liệu này được lưu trữ trong tệp extension.yaml
.
Mở
extension.yaml
trong trình chỉnh sửa và thay thế toàn bộ nội dung của tệp bằng nội dung sau:name: rtdb-uppercase-messages version: 0.0.1 specVersion: v1beta # Firebase Extensions specification version; don't change # Friendly display name for your extension (~3-5 words) displayName: Convert messages to upper case # Brief description of the task your extension performs (~1 sentence) description: >- Converts messages in RTDB to upper case author: authorName: Your Name url: https://your-site.example.com license: Apache-2.0 # Required license # Public URL for the source code of your extension sourceUrl: https://github.com/your-name/your-repo
Lưu ý quy ước đặt tên được sử dụng trong trường
name
: các tiện ích Firebase chính thức được đặt tên bằng một tiền tố cho biết sản phẩm Firebase chính mà tiện ích hoạt động, theo sau là nội dung mô tả về chức năng của tiện ích. Bạn nên sử dụng cùng một quy ước trong các tiện ích của riêng mình.Vì đã thay đổi tên của tiện ích, nên bạn cũng nên cập nhật tên mới cho cấu hình trình mô phỏng:
- Trong
functions/integration-tests/firebase.json
, hãy thay đổigreet-the-world
thànhrtdb-uppercase-messages
. - Đổi tên
functions/integration-tests/extensions/greet-the-world.env
thànhfunctions/integration-tests/extensions/rtdb-uppercase-messages.env
.
- Trong
Vẫn còn một số phần còn lại của tiện ích greet-the-world
trong mã tiện ích của bạn, nhưng hiện tại, hãy để lại các phần đó. Bạn sẽ cập nhật các thông tin đó trong vài phần tiếp theo.
4. Viết một Hàm trên đám mây và khai báo hàm đó dưới dạng tài nguyên tiện ích
Bây giờ, bạn có thể bắt đầu viết một số mã. Ở bước này, bạn sẽ viết một Hàm trên đám mây thực hiện nhiệm vụ cốt lõi của tiện ích, đó là theo dõi Cơ sở dữ liệu theo thời gian thực để tìm thông báo và chuyển đổi thông báo đó thành viết hoa.
Mở nguồn cho các hàm của tiện ích (trong thư mục
functions
của tiện ích) trong trình chỉnh sửa hoặc IDE mà bạn chọn. Thay thế nội dung của tệp này bằng nội dung sau:functions/index.js
import { database, logger } from "firebase-functions/v1"; const app = initializeApp(); // Listens for new messages added to /messages/{pushId}/original and creates an // uppercase version of the message to /messages/{pushId}/uppercase // for all databases in 'us-central1' export const makeuppercase = database .ref("/messages/{pushId}/uppercase") .onCreate(async (snapshot, context) => { // Grab the current value of what was written to the Realtime Database. const original = snapshot.val(); // Convert it to upper case. logger.log("Uppercasing", context.params.pushId, original); const uppercase = original.toUpperCase(); // Setting an "uppercase" sibling in the Realtime Database. const upperRef = snapshot.ref.parent.child("upper"); await upperRef.set(uppercase); });
Hàm cũ mà bạn đã thay thế là một hàm được kích hoạt bằng HTTP, chạy khi truy cập vào một điểm cuối HTTP. Hàm mới được kích hoạt bằng các sự kiện cơ sở dữ liệu theo thời gian thực: hàm này theo dõi các mục mới tại một đường dẫn cụ thể và khi phát hiện thấy một mục, hàm này sẽ ghi phiên bản viết hoa của giá trị đó vào cơ sở dữ liệu.
Nhân tiện, tệp mới này sử dụng cú pháp mô-đun ECMAScript (
import
vàexport
) thay vì CommonJS (require
). Để sử dụng các mô-đun ES trong Node, hãy chỉ định"type": "module"
trongfunctions/package.json
:{ "name": "rtdb-uppercase-messages", "main": "index.js", "type": "module", … }
Bạn phải khai báo mọi hàm trong tiện ích trong tệp
extension.yaml
. Tiện ích mẫu đã khai báogreetTheWorld
là Hàm trên đám mây duy nhất của tiện ích; giờ đây, khi đã thay thế hàm này bằngmakeuppercase
, bạn cũng cần cập nhật nội dung khai báo của hàm.Mở
extension.yaml
và thêm trườngresources
:resources: - name: makeuppercase type: firebaseextensions.v1beta.function properties: eventTrigger: eventType: providers/google.firebase.database/eventTypes/ref.create # DATABASE_INSTANCE (project's default instance) is an auto-populated # parameter value. You can also specify an instance. resource: projects/_/instances/${DATABASE_INSTANCE}/refs/messages/{pushId}/original runtime: "nodejs18"
Vì tiện ích của bạn hiện đang sử dụng Cơ sở dữ liệu theo thời gian thực làm trình kích hoạt, nên bạn cần cập nhật cấu hình trình mô phỏng để chạy trình mô phỏng RTDB cùng với trình mô phỏng Cloud Functions:
Nếu trình mô phỏng vẫn đang chạy, hãy dừng trình mô phỏng bằng cách nhấn tổ hợp phím Ctrl-C.
Từ thư mục
functions/integration-tests
, hãy chạy lệnh sau:firebase init emulators
Khi được hỏi, hãy bỏ qua việc thiết lập dự án mặc định, sau đó chọn trình mô phỏng Hàm và Cơ sở dữ liệu. Chấp nhận các cổng mặc định và cho phép công cụ thiết lập tải mọi tệp cần thiết xuống.
Khởi động lại trình mô phỏng:
firebase emulators:start --project=demo-test
Dùng thử tiện ích đã cập nhật:
Mở giao diện người dùng của trình mô phỏng Cơ sở dữ liệu bằng đường liên kết mà trình mô phỏng in ra khi bạn khởi động.
Chỉnh sửa nút gốc của cơ sở dữ liệu:
- Trường:
messages
- Loại:
json
- Giá trị:
{"11": {"original": "recipe"}}
Nếu bạn thiết lập mọi thứ chính xác, khi bạn lưu các thay đổi đối với cơ sở dữ liệu, hàm
makeuppercase
của tiện ích sẽ kích hoạt và thêm một bản ghi con vào thông báo 11 với nội dung"upper": "RECIPE"
. Hãy xem các nhật ký và thẻ cơ sở dữ liệu của giao diện người dùng trình mô phỏng để xác nhận kết quả dự kiến.- Trường:
Hãy thử thêm một số phần tử con khác vào nút
messages
({"original":"any text"}
). Bất cứ khi nào bạn thêm một bản ghi mới, tiện ích sẽ thêm một trườnguppercase
chứa nội dung viết hoa của trườngoriginal
.
Giờ đây, bạn đã có một tiện ích hoàn chỉnh, mặc dù đơn giản, hoạt động trên một thực thể RTDB. Trong các phần tiếp theo, bạn sẽ tinh chỉnh tiện ích này bằng một số tính năng bổ sung. Sau đó, bạn sẽ sẵn sàng phân phối tiện ích cho người khác và cuối cùng, tìm hiểu cách phát hành tiện ích trên Trung tâm tiện ích.
5. Khai báo API và vai trò
Firebase cấp cho mỗi thực thể của một tiện ích đã cài đặt quyền truy cập hạn chế vào dự án và dữ liệu của dự án đó bằng cách sử dụng tài khoản dịch vụ cho mỗi thực thể. Mỗi tài khoản có số lượng quyền tối thiểu cần thiết để hoạt động. Vì lý do này, bạn phải khai báo rõ ràng mọi vai trò IAM mà tiện ích của bạn yêu cầu; khi người dùng cài đặt tiện ích, Firebase sẽ tạo một tài khoản dịch vụ được cấp các vai trò này và sử dụng tài khoản đó để chạy tiện ích.
Bạn không cần khai báo vai trò để kích hoạt các sự kiện của sản phẩm, nhưng bạn cần khai báo vai trò để tương tác với sản phẩm. Vì hàm bạn thêm vào bước cuối cùng sẽ ghi vào Cơ sở dữ liệu theo thời gian thực, nên bạn cần thêm nội dung khai báo sau vào extension.yaml
:
roles:
- role: firebasedatabase.admin
reason: Allows the extension to write to RTDB.
Tương tự, bạn khai báo các API Google mà một tiện ích sử dụng trong trường apis
. Khi người dùng cài đặt tiện ích của bạn, họ sẽ được hỏi xem họ có muốn tự động bật các API này cho dự án của mình hay không. Việc này thường chỉ cần thiết đối với các API Google không phải Firebase và không cần thiết đối với hướng dẫn này.
6. Xác định các thông số mà người dùng có thể định cấu hình
Hàm bạn đã tạo trong hai bước cuối cùng đã theo dõi một vị trí RTDB cụ thể cho các thông báo đến. Đôi khi, bạn thực sự muốn theo dõi một vị trí cụ thể, chẳng hạn như khi tiện ích của bạn hoạt động trên một cấu trúc cơ sở dữ liệu mà bạn chỉ sử dụng cho tiện ích của mình. Tuy nhiên, trong hầu hết trường hợp, bạn sẽ muốn những người dùng cài đặt tiện ích của bạn trong dự án của họ có thể định cấu hình các giá trị này. Bằng cách này, người dùng có thể sử dụng tiện ích của bạn để làm việc với chế độ thiết lập cơ sở dữ liệu hiện có.
Đặt đường dẫn mà tiện ích xem cho các tin nhắn mới ở chế độ có thể định cấu hình cho người dùng:
Trong tệp
extension.yaml
, hãy thêm phầnparams
:- param: MESSAGE_PATH label: Message path description: >- What is the path at which the original text of a message can be found? type: string default: /messages/{pushId}/original required: true immutable: false
Thao tác này xác định một tham số chuỗi mới mà người dùng sẽ được nhắc đặt khi cài đặt tiện ích của bạn.
Vẫn trong tệp
extension.yaml
, hãy quay lại phần khai báomakeuppercase
và thay đổi trườngresource
thành nội dung sau:resource: projects/_/instances/${DATABASE_INSTANCE}/refs/${param:MESSAGE_PATH}
Mã thông báo
${param:MESSAGE_PATH}
là tham chiếu đến tham số bạn vừa xác định. Khi tiện ích của bạn chạy, mã thông báo này sẽ được thay thế bằng bất kỳ giá trị nào mà người dùng đã định cấu hình cho tham số đó, kết quả là hàmmakeuppercase
sẽ theo dõi đường dẫn mà người dùng chỉ định. Bạn có thể sử dụng cú pháp này để tham chiếu bất kỳ tham số nào do người dùng xác định ở bất kỳ đâu trongextension.yaml
(và trongPOSTINSTALL.md
– sẽ nói thêm về điều này sau).Bạn cũng có thể truy cập vào các tham số do người dùng xác định từ mã hàm.
Trong hàm đã viết ở phần trước, bạn đã mã hoá cứng đường dẫn để xem các thay đổi. Thay đổi định nghĩa điều kiện kích hoạt để tham chiếu đến giá trị do người dùng xác định:
functions/index.js
export const makeuppercase = database.ref(process.env.MESSAGE_PATH).onCreate
Xin lưu ý rằng trong Tiện ích Firebase, thay đổi này chỉ nhằm mục đích tài liệu: khi một Hàm trên đám mây được triển khai như một phần của tiện ích, hàm đó sẽ sử dụng định nghĩa điều kiện kích hoạt từ tệp
extension.yaml
và bỏ qua giá trị được chỉ định trong định nghĩa hàm. Tuy nhiên, bạn nên ghi lại trong mã nguồn nguồn gốc của giá trị này.Bạn có thể thất vọng khi thay đổi mã không có hiệu lực về thời gian chạy, nhưng bài học quan trọng cần rút ra là bạn có thể truy cập vào bất kỳ tham số nào do người dùng xác định trong mã hàm và sử dụng tham số đó làm giá trị thông thường trong logic của hàm. Để thể hiện khả năng này, hãy thêm câu lệnh nhật ký sau để chứng minh rằng bạn thực sự đang truy cập vào giá trị mà người dùng đã xác định:
functions/index.js
export const makeuppercase = database.ref(process.env.MESSAGE_PATH).onCreate( async (snapshot, context) => { logger.log("Found new message at ", snapshot.ref); // Grab the current value of what was written to the Realtime Database. ...
Thông thường, người dùng sẽ được nhắc cung cấp giá trị cho các thông số khi họ cài đặt một tiện ích. Tuy nhiên, khi sử dụng trình mô phỏng để kiểm thử và phát triển, bạn sẽ bỏ qua quy trình cài đặt, do đó, bạn sẽ cung cấp giá trị cho các thông số do người dùng xác định bằng cách sử dụng tệp
env
.Mở
functions/integration-tests/extensions/rtdb-uppercase-messages.env
rồi thay thế định nghĩaGREETING
bằng nội dung sau:MESSAGE_PATH=/msgs/{pushId}/original
Lưu ý rằng đường dẫn ở trên khác với đường dẫn mặc định và đường dẫn bạn đã xác định trước đó; điều này chỉ để chứng minh cho bạn khi bạn thử phần mở rộng đã cập nhật rằng định nghĩa của bạn đang có hiệu lực.
Bây giờ, hãy khởi động lại trình mô phỏng và truy cập lại giao diện người dùng của trình mô phỏng cơ sở dữ liệu.
Chỉnh sửa nút gốc của cơ sở dữ liệu bằng đường dẫn bạn đã xác định ở trên:
- Trường:
msgs
- Loại:
json
- Giá trị:
{"11": {"original": "recipe"}}
Khi bạn lưu các thay đổi đối với cơ sở dữ liệu, hàm
makeuppercase
của tiện ích sẽ kích hoạt như trước, nhưng giờ đây, hàm này cũng sẽ in tham số do người dùng xác định vào nhật ký bảng điều khiển.- Trường:
7. Cung cấp hook sự kiện cho logic do người dùng xác định
Là tác giả của tiện ích, bạn đã thấy cách một sản phẩm Firebase có thể kích hoạt logic do tiện ích cung cấp: việc tạo bản ghi mới trong Cơ sở dữ liệu theo thời gian thực sẽ kích hoạt hàm makeuppercase
. Tiện ích của bạn có thể có mối quan hệ tương tự với những người dùng cài đặt tiện ích: tiện ích có thể kích hoạt logic mà người dùng xác định.
Mỗi tiện ích có thể cung cấp hook đồng bộ, hook không đồng bộ hoặc cả hai. Các móc đồng bộ cho phép người dùng thực hiện các tác vụ chặn việc hoàn tất một trong các chức năng của tiện ích. Điều này có thể hữu ích, chẳng hạn như để cung cấp cho người dùng một cách để thực hiện quá trình xử lý trước tuỳ chỉnh trước khi một tiện ích thực hiện công việc của mình.
Trong hướng dẫn này, bạn sẽ thêm một trình kích hoạt không đồng bộ vào tiện ích của mình. Trình kích hoạt này sẽ cho phép người dùng xác định các bước xử lý của riêng họ để chạy sau khi tiện ích của bạn ghi thông báo viết hoa vào Cơ sở dữ liệu theo thời gian thực. Các hook không đồng bộ sử dụng Eventarc để kích hoạt các hàm do người dùng xác định. Tiện ích khai báo các loại sự kiện mà chúng phát ra và khi người dùng cài đặt tiện ích, họ sẽ chọn loại sự kiện mà họ quan tâm. Nếu người dùng chọn ít nhất một sự kiện, Firebase sẽ cấp một kênh Eventarc cho tiện ích trong quá trình cài đặt. Sau đó, người dùng có thể triển khai các chức năng đám mây của riêng họ để nghe trên kênh đó và kích hoạt khi tiện ích phát hành sự kiện mới.
Hãy làm theo các bước sau để thêm một trình bổ trợ không đồng bộ:
Trong tệp
extension.yaml
, hãy thêm phần sau đây để khai báo một loại sự kiện mà tiện ích phát ra:events: - type: test-publisher.rtdb-uppercase-messages.v1.complete description: >- Occurs when message uppercasing completes. The event subject will contain the RTDB URL of the uppercase message.
Các loại sự kiện phải là duy nhất trên toàn hệ thống; để đảm bảo tính duy nhất, hãy luôn đặt tên cho sự kiện theo định dạng sau:
<publisher-id>.<extension-id>.<version>.<description>
. (Bạn chưa có mã nhận dạng nhà xuất bản, vì vậy, hãy sử dụngtest-publisher
.)Ở cuối hàm
makeuppercase
, hãy thêm một số mã phát hành một sự kiện thuộc loại bạn vừa khai báo:functions/index.js
// Import the Eventarc library: import { initializeApp } from "firebase-admin/app"; import { getEventarc } from "firebase-admin/eventarc"; const app = initializeApp(); // In makeuppercase, after upperRef.set(uppercase), add: // Set eventChannel to a newly-initialized channel, or `undefined` if events // aren't enabled. const eventChannel = process.env.EVENTARC_CHANNEL && getEventarc().channel(process.env.EVENTARC_CHANNEL, { allowedEventTypes: process.env.EXT_SELECTED_EVENTS, }); // If events are enabled, publish a `complete` event to the configured // channel. eventChannel && eventChannel.publish({ type: "test-publisher.rtdb-uppercase-messages.v1.complete", subject: upperRef.toString(), data: { "original": original, "uppercase": uppercase, }, });
Mã ví dụ này tận dụng thực tế là biến môi trường
EVENTARC_CHANNEL
chỉ được xác định khi người dùng bật ít nhất một loại sự kiện. Nếu không xác địnhEVENTARC_CHANNEL
, mã sẽ không tìm cách xuất bản bất kỳ sự kiện nào.Bạn có thể đính kèm thêm thông tin vào một sự kiện Eventarc. Trong ví dụ trên, sự kiện có một trường
subject
chứa tham chiếu đến giá trị mới tạo và một tải trọngdata
chứa thông báo gốc và thông báo viết hoa. Các hàm do người dùng xác định kích hoạt sự kiện có thể sử dụng thông tin này.Thông thường, các biến môi trường
EVENTARC_CHANNEL
vàEXT_SELECTED_EVENTS
được xác định dựa trên các tuỳ chọn mà người dùng đã chọn trong quá trình cài đặt. Để kiểm thử bằng trình mô phỏng, hãy xác định các biến này theo cách thủ công trong tệprtdb-uppercase-messages.env
:EVENTARC_CHANNEL=locations/us-central1/channels/firebase EXT_SELECTED_EVENTS=test-publisher.rtdb-uppercase-messages.v1.complete
Tại thời điểm này, bạn đã hoàn tất các bước cần thiết để thêm một trình kích hoạt sự kiện không đồng bộ vào tiện ích.
Để dùng thử tính năng mới mà bạn vừa triển khai, trong vài bước tiếp theo, hãy giả định vai trò của một người dùng đang cài đặt tiện ích:
Từ thư mục
functions/integration-tests
, hãy khởi chạy một dự án Firebase mới:firebase init functions
Khi được nhắc, hãy từ chối thiết lập dự án mặc định, chọn JavaScript làm ngôn ngữ của Hàm trên đám mây và cài đặt các phần phụ thuộc bắt buộc. Dự án này đại diện cho dự án của người dùng, trong đó đã cài đặt tiện ích của bạn.
Chỉnh sửa
integration-tests/functions/index.js
và dán mã sau:import { logger } from "firebase-functions/v1"; import { onCustomEventPublished } from "firebase-functions/v2/eventarc"; import { initializeApp } from "firebase-admin/app"; import { getDatabase } from "firebase-admin/database"; const app = initializeApp(); export const extraemphasis = onCustomEventPublished( "test-publisher.rtdb-uppercase-messages.v1.complete", async (event) => { logger.info("Received makeuppercase completed event", event); const refUrl = event.subject; const ref = getDatabase().refFromURL(refUrl); const upper = (await ref.get()).val(); return ref.set(`${upper}!!!`); } );
Đây là ví dụ về một hàm xử lý hậu kỳ mà người dùng có thể viết. Trong trường hợp này, hàm sẽ nghe tiện ích phát hành một sự kiện
complete
và khi được kích hoạt, hàm sẽ thêm ba dấu chấm than vào thông báo mới được viết hoa.Khởi động lại trình mô phỏng. Trình mô phỏng sẽ tải các hàm của tiện ích cũng như hàm xử lý hậu kỳ mà "người dùng" đã xác định.
Truy cập vào giao diện người dùng của trình mô phỏng cơ sở dữ liệu và chỉnh sửa nút gốc của cơ sở dữ liệu bằng cách sử dụng đường dẫn mà bạn đã xác định ở trên:
- Trường:
msgs
- Loại:
json
- Giá trị:
{"11": {"original": "recipe"}}
Khi bạn lưu các thay đổi đối với cơ sở dữ liệu, hàm
makeuppercase
của tiện ích và hàmextraemphasis
của người dùng sẽ kích hoạt theo trình tự, dẫn đến trườngupper
nhận được giá trịRECIPE!!!
.- Trường:
8. Thêm trình xử lý sự kiện trong vòng đời
Tiện ích bạn đã viết cho đến nay xử lý các thông báo khi chúng được tạo. Nhưng nếu người dùng của bạn đã có cơ sở dữ liệu tin nhắn khi cài đặt tiện ích thì sao? Tiện ích Firebase có một tính năng gọi là móc sự kiện trong vòng đời mà bạn có thể sử dụng để kích hoạt các hành động khi tiện ích được cài đặt, cập nhật hoặc định cấu hình lại. Trong phần này, bạn sẽ sử dụng các hook sự kiện trong vòng đời để bổ sung các thông báo được viết hoa khi người dùng cài đặt tiện ích của bạn vào cơ sở dữ liệu thông báo hiện có của dự án.
Tiện ích Firebase sử dụng Cloud Tasks để chạy trình xử lý sự kiện trong vòng đời. Bạn xác định trình xử lý sự kiện bằng cách sử dụng Hàm trên đám mây; bất cứ khi nào một thực thể của tiện ích đạt đến một trong các sự kiện trong vòng đời được hỗ trợ, nếu bạn đã xác định trình xử lý, thì trình xử lý đó sẽ thêm trình xử lý vào hàng đợi của Cloud Tasks. Sau đó, Cloud Tasks sẽ thực thi trình xử lý một cách không đồng bộ. Khi trình xử lý sự kiện trong vòng đời đang chạy, bảng điều khiển của Firebase sẽ báo cáo cho người dùng rằng phiên bản tiện ích có một tác vụ xử lý đang được xử lý. Chức năng xử lý của bạn phụ thuộc vào việc báo cáo trạng thái liên tục và việc hoàn thành tác vụ cho người dùng.
Để thêm trình xử lý sự kiện trong vòng đời giúp bổ sung các thông báo hiện có, hãy làm như sau:
Xác định một Hàm trên đám mây mới được kích hoạt bằng các sự kiện hàng đợi tác vụ:
functions/index.js
import { tasks } from "firebase-functions/v1"; import { getDatabase } from "firebase-admin/database"; import { getExtensions } from "firebase-admin/extensions"; import { getFunctions } from "firebase-admin/functions"; export const backfilldata = tasks.taskQueue().onDispatch(async () => { const batch = await getDatabase() .ref(process.env.MESSAGE_PATH) .parent.parent.orderByChild("upper") .limitToFirst(20) .get(); const promises = []; for (const key in batch.val()) { const msg = batch.child(key); if (msg.hasChild("original") && !msg.hasChild("upper")) { const upper = msg.child("original").val().toUpperCase(); promises.push(msg.child("upper").ref.set(upper)); } } await Promise.all(promises); if (promises.length > 0) { const queue = getFunctions().taskQueue( "backfilldata", process.env.EXT_INSTANCE_ID ); return queue.enqueue({}); } else { return getExtensions() .runtime() .setProcessingState("PROCESSING_COMPLETE", "Backfill complete."); } });
Lưu ý rằng hàm này chỉ xử lý một vài bản ghi trước khi tự thêm vào hàng đợi tác vụ. Đây là chiến lược thường dùng để xử lý các tác vụ xử lý không thể hoàn tất trong khoảng thời gian chờ của Hàm trên đám mây. Vì bạn không thể dự đoán số lượng thông báo mà người dùng có thể đã có trong cơ sở dữ liệu khi họ cài đặt tiện ích của bạn, nên chiến lược này rất phù hợp.
Trong tệp
extension.yaml
, hãy khai báo hàm thay thế dưới dạng một tài nguyên tiện ích có thuộc tínhtaskQueueTrigger
:resources: - name: makeuppercase ... - name: backfilldata type: firebaseextensions.v1beta.function description: >- Backfill existing messages with uppercase versions properties: runtime: "nodejs18" taskQueueTrigger: {}
Sau đó, hãy khai báo hàm này làm trình xử lý cho sự kiện trong vòng đời
onInstall
:lifecycleEvents: onInstall: function: backfilldata processingMessage: Uppercasing existing messages
Mặc dù việc bổ sung lại các tin nhắn hiện có là rất hữu ích, nhưng tiện ích này vẫn có thể hoạt động mà không cần tính năng này. Trong những trường hợp như vậy, bạn nên chạy trình xử lý sự kiện trong vòng đời (không bắt buộc).
Để thực hiện việc này, hãy thêm một tham số mới vào
extension.yaml
:- param: DO_BACKFILL label: Backfill existing messages description: >- Generate uppercase versions of existing messages? type: select required: true options: - label: Yes value: true - label: No value: false
Sau đó, ở đầu hàm điền lại, hãy kiểm tra giá trị của tham số
DO_BACKFILL
và thoát sớm nếu tham số này không được đặt:functions/index.js
if (!process.env.DO_BACKFILL) { return getExtensions() .runtime() .setProcessingState("PROCESSING_COMPLETE", "Backfill skipped."); }
Với những thay đổi trên, tiện ích này hiện sẽ chuyển đổi các thông báo hiện có sang chữ hoa khi được cài đặt.
Đến thời điểm này, bạn đã sử dụng trình mô phỏng tiện ích để phát triển tiện ích và kiểm thử các thay đổi đang diễn ra. Tuy nhiên, trình mô phỏng tiện ích sẽ bỏ qua quá trình cài đặt. Vì vậy, để kiểm thử trình xử lý sự kiện onInstall
, bạn cần cài đặt tiện ích trong một dự án thực. Mặc dù vậy, cũng chỉ là như vậy, vì khi được bổ sung
tính năng chèn lấp tự động này, tiện ích hướng dẫn hiện đã mã hoàn chỉnh!
9. Triển khai vào một dự án Firebase thực
Mặc dù trình mô phỏng tiện ích là một công cụ tuyệt vời để lặp lại nhanh một tiện ích trong quá trình phát triển, nhưng tại một thời điểm nào đó, bạn sẽ muốn thử công cụ này trong một dự án thực tế.
Để thực hiện việc này, trước tiên, hãy thiết lập một dự án mới đã bật một số dịch vụ:
- Trong bảng điều khiển của Firebase, hãy thêm một dự án mới.
- Nâng cấp dự án lên gói Blaze trả theo mức sử dụng. Cloud Functions for Firebase yêu cầu dự án của bạn phải có tài khoản thanh toán, vì vậy, bạn cũng cần có tài khoản thanh toán để cài đặt tiện ích.
- Trong dự án mới, hãy bật Cơ sở dữ liệu theo thời gian thực.
- Vì bạn muốn kiểm tra khả năng của tiện ích trong việc bổ sung dữ liệu hiện có khi cài đặt, hãy nhập một số dữ liệu mẫu vào thực thể cơ sở dữ liệu theo thời gian thực:
- Tải một số dữ liệu RTDB gốc xuống.
- Trên trang Cơ sở dữ liệu theo thời gian thực của bảng điều khiển Firebase, hãy nhấp vào biểu tượng (thêm) > Nhập JSON rồi chọn tệp bạn vừa tải xuống.
Để cho phép hàm điền lấp sử dụng phương thức
orderByChild
, hãy định cấu hình cơ sở dữ liệu để lập chỉ mục thông báo theo giá trị củaupper
:{ "rules": { ".read": false, ".write": false, "messages": { ".indexOn": "upper" } } }
Bây giờ, hãy cài đặt tiện ích của bạn từ nguồn cục bộ vào dự án mới:
Tạo thư mục mới cho dự án Firebase:
mkdir ~/extensions-live-test && cd ~/extensions-live-test
Khởi chạy dự án Firebase trong thư mục đang hoạt động:
firebase init database
Khi được nhắc, hãy chọn dự án bạn vừa tạo.
Cài đặt tiện ích vào dự án Firebase cục bộ:
firebase ext:install /path/to/rtdb-uppercase-messages
Tại đây, bạn có thể xem trải nghiệm người dùng khi cài đặt một tiện ích bằng công cụ Firebase CLI. Hãy nhớ chọn "có" khi công cụ cấu hình hỏi bạn có muốn bổ sung cơ sở dữ liệu hiện có không.
Sau khi bạn chọn các tuỳ chọn cấu hình, Firebase CLI sẽ lưu cấu hình của bạn trong thư mục
extensions
và ghi lại vị trí nguồn mở rộng trong tệpfirebase.json
. Tổng cộng, hai bản ghi này được gọi là tệp kê khai tiện ích. Người dùng có thể sử dụng tệp kê khai để lưu cấu hình tiện ích và triển khai cấu hình đó cho nhiều dự án.Triển khai cấu hình tiện ích cho dự án đang hoạt động:
firebase deploy --only extensions
Nếu mọi thứ diễn ra suôn sẻ, CLI Firebase sẽ tải tiện ích của bạn lên dự án và cài đặt tiện ích đó. Sau khi cài đặt xong, tác vụ điền lại sẽ chạy và trong vài phút, cơ sở dữ liệu của bạn sẽ được cập nhật bằng các thông báo viết hoa. Thêm một số nút mới vào cơ sở dữ liệu tin nhắn và đảm bảo phần mở rộng cũng hoạt động cho các tin nhắn mới.
10. Viết tài liệu
Trước khi bạn chia sẻ tiện ích với người dùng, hãy đảm bảo bạn cung cấp đủ tài liệu để giúp họ thành công.
Khi bạn khởi chạy dự án tiện ích, CLI Firebase đã tạo các phiên bản mô phỏng của tài liệu tối thiểu bắt buộc. Cập nhật các tệp này để phản ánh chính xác phần mở rộng mà bạn đã tạo.
extension.yaml
Bạn đã cập nhật tệp này khi phát triển tiện ích này, vì vậy, bạn không cần cập nhật thêm nữa.
Tuy nhiên, đừng bỏ qua tầm quan trọng của tài liệu có trong tệp này. Ngoài thông tin nhận dạng quan trọng của một tiện ích (tên, nội dung mô tả, tác giả, vị trí kho lưu trữ chính thức), tệp extension.yaml
còn chứa tài liệu dành cho người dùng về mọi tài nguyên và tham số mà người dùng có thể định cấu hình. Thông tin này được hiển thị cho người dùng trong bảng điều khiển của Firebase, Trung tâm tiện ích và Firebase CLI.
PREINSTALL.md
Trong tệp này, hãy cung cấp thông tin mà người dùng cần trước khi cài đặt tiện ích: mô tả ngắn gọn về chức năng của tiện ích, giải thích mọi điều kiện tiên quyết và cung cấp cho người dùng thông tin về các vấn đề liên quan đến việc thanh toán khi cài đặt tiện ích. Nếu bạn có một trang web có thông tin bổ sung, đây cũng là một vị trí phù hợp để liên kết trang web đó.
Văn bản của tệp này sẽ hiển thị cho người dùng trong Trung tâm tiện ích và theo lệnh firebase ext:info
.
Dưới đây là ví dụ về tệp PREINSTALL:
Use this extension to automatically convert strings to upper case when added to
a specified Realtime Database path.
This extension expects a database layout like the following example:
"messages": {
MESSAGE_ID: {
"original": MESSAGE_TEXT
},
MESSAGE_ID: {
"original": MESSAGE_TEXT
},
}
When you create new string records, this extension creates a new sibling record
with upper-cased text:
MESSAGE_ID: {
"original": MESSAGE_TEXT,
"upper": UPPERCASE_MESSAGE_TEXT,
}
#### Additional setup
Before installing this extension, make sure that you've
[set up Realtime Database](https://firebase.google.com/docs/database/quickstart)
in your Firebase project.
#### Billing
To install an extension, your project must be on the
[Blaze (pay as you go) plan](https://firebase.google.com/pricing).
- This extension uses other Firebase and Google Cloud Platform services, which
have associated charges if you exceed the service's no-cost tier:
- Realtime Database
- Cloud Functions (Node.js 10+ runtime)
[See FAQs](https://firebase.google.com/support/faq#extensions-pricing)
- If you enable events,
[Eventarc fees apply](https://cloud.google.com/eventarc/pricing).
POSTINSTALL.md
Tệp này chứa thông tin hữu ích cho người dùng sau khi họ cài đặt thành công tiện ích của bạn: ví dụ: các bước thiết lập tiếp theo, ví dụ về cách sử dụng tiện ích, v.v.
Nội dung của POSTINSTALL.md sẽ xuất hiện trong bảng điều khiển Firebase sau khi bạn định cấu hình và cài đặt một tiện ích. Bạn có thể tham chiếu các tham số người dùng trong tệp này. Các tham số đó sẽ được thay thế bằng các giá trị đã định cấu hình.
Dưới đây là ví dụ về tệp sau khi cài đặt cho tiện ích hướng dẫn:
### See it in action
You can test out this extension right away!
1. Go to your
[Realtime Database dashboard](https://console.firebase.google.com/project/${param:PROJECT_ID}/database/${param:PROJECT_ID}/data) in the Firebase console.
1. Add a message string to a path that matches the pattern `${param:MESSAGE_PATH}`.
1. In a few seconds, you'll see a sibling node named `upper` that contains the
message in upper case.
### Using the extension
We recommend adding data by pushing -- for example,
`firebase.database().ref().push()` -- because pushing assigns an automatically
generated ID to the node in the database. During retrieval, these nodes are
guaranteed to be ordered by the time they were added. Learn more about reading
and writing data for your platform (iOS, Android, or Web) in the
[Realtime Database documentation](https://firebase.google.com/docs/database/).
### Monitoring
As a best practice, you can
[monitor the activity](https://firebase.google.com/docs/extensions/manage-installed-extensions#monitor)
of your installed extension, including checks on its health, usage, and logs.
CHANGELOG.md
Bạn cũng nên ghi lại các thay đổi mà bạn thực hiện giữa các bản phát hành của một tiện ích trong tệp CHANGELOG.md
.
Vì tiện ích mẫu chưa từng được xuất bản trước đó, nên nhật ký thay đổi chỉ có một mục nhập:
## Version 0.0.1
Initial release of the _Convert messages to upper case_ extension.
README.md
Hầu hết tiện ích cũng cung cấp tệp đọc tôi để người dùng truy cập vào kho lưu trữ của tiện ích. Bạn có thể viết tệp này theo cách thủ công hoặc tạo một tệp đọc cho tôi bằng lệnh.
Để phù hợp với mục đích của hướng dẫn này, hãy bỏ qua việc viết tệp readme.
Tài liệu bổ sung
Tài liệu thảo luận ở trên là bộ tài liệu tối thiểu mà bạn nên cung cấp cho người dùng. Nhiều tiện ích yêu cầu tài liệu chi tiết hơn để người dùng có thể sử dụng thành công. Trong trường hợp này, bạn nên viết thêm tài liệu và lưu trữ tài liệu đó ở nơi bạn có thể trỏ người dùng đến.
Để phù hợp với mục đích của hướng dẫn này, hãy bỏ qua việc viết tài liệu chi tiết hơn.
11. Xuất bản trên Trung tâm tiện ích
Giờ đây, khi tiện ích của bạn đã hoàn tất mã và được ghi lại, bạn đã sẵn sàng chia sẻ tiện ích đó với mọi người trên Trung tâm tiện ích. Tuy nhiên, vì đây chỉ là hướng dẫn, nên bạn đừng thực sự làm như vậy. Hãy bắt đầu viết tiện ích của riêng bạn bằng những gì bạn đã học được tại đây và trong phần còn lại của tài liệu dành cho nhà xuất bản Tiện ích Firebase, cũng như bằng cách kiểm tra nguồn của các tiện ích chính thức do Firebase viết.
Khi bạn đã sẵn sàng xuất bản tác phẩm của mình trên Trung tâm tiện ích, sau đây là cách bạn sẽ thực hiện:
- Nếu bạn đang phát hành tiện ích đầu tiên, hãy đăng ký làm nhà xuất bản tiện ích. Khi đăng ký làm nhà xuất bản tiện ích, bạn sẽ tạo một mã nhà xuất bản để người dùng nhanh chóng xác định bạn là tác giả của tiện ích.
Lưu trữ mã nguồn của tiện ích ở một vị trí có thể xác minh công khai. Khi mã của bạn có sẵn từ một nguồn có thể xác minh, Firebase có thể phát hành trực tiếp tiện ích của bạn từ vị trí này. Việc này giúp đảm bảo rằng bạn đang phát hành phiên bản tiện ích hiện đã phát hành và giúp người dùng bằng cách cho phép họ kiểm tra mã mà họ đang cài đặt vào dự án của mình.
Hiện tại, bạn cần cung cấp tiện ích trong một kho lưu trữ GitHub công khai.
Tải tiện ích của bạn lên Trung tâm tiện ích bằng lệnh
firebase ext:dev:upload
.Chuyển đến trang tổng quan dành cho nhà xuất bản trong bảng điều khiển Firebase, tìm tiện ích mà bạn vừa tải lên rồi nhấp vào "Xuất bản lên Trung tâm tiện ích". Việc này sẽ yêu cầu nhân viên đánh giá của chúng tôi xem xét. Quá trình này có thể mất vài ngày. Nếu được phê duyệt, tiện ích sẽ được phát hành lên Trung tâm tiện ích. Nếu bị từ chối, bạn sẽ nhận được thông báo giải thích lý do. Sau đó, bạn có thể giải quyết các vấn đề đã báo cáo rồi gửi lại để được xem xét.