1. Trước khi bạn bắt đầu
Tiện ích mở rộng Firebase thực hiện một nhiệm vụ hoặc tập hợp nhiệm vụ cụ thể để đáp ứng các yêu cầu HTTP hoặc kích hoạt các sự kiện từ các sản phẩm Firebase và Google khác như Firebase Cloud Messaging, Cloud Firestore hoặc Pub/Sub.
Những gì bạn sẽ xây dựng
Trong lớp học lập trình này, bạn sẽ xây dựng tiện ích Firebase để băm địa lý . Sau khi được triển khai, tiện ích mở rộng của bạn sẽ chuyển đổi tọa độ X và Y thành geohash để phản hồi các sự kiện của Firestore hoặc thông qua các lệnh gọi hàm có thể gọi được. Điều này có thể được sử dụng như một giải pháp thay thế cho việc triển khai thư viện geofire trên tất cả các nền tảng mục tiêu của bạn để lưu trữ dữ liệu, giúp bạn tiết kiệm thời gian.
Bạn sẽ học được gì
- Cách lấy mã Chức năng đám mây hiện có và biến nó thành Tiện ích mở rộng Firebase có thể phân phối
- Cách thiết lập tệp
extension.yaml
- Cách lưu trữ chuỗi nhạy cảm (khóa API) trong tiện ích mở rộng
- Cách cho phép các nhà phát triển tiện ích mở rộng định cấu hình tiện ích mở rộng cho phù hợp với nhu cầu của họ
- Cách kiểm tra và triển khai tiện ích mở rộng
Những gì bạn cần
- Firebase CLI (cài đặt và đăng nhập)
- Tài khoản Google, giống như tài khoản gmail
- Node.js và
npm
- Môi trường phát triển yêu thích của bạn
2. Thiết lập
Lấy mã
Mọi thứ bạn cần cho tiện ích mở rộng này đều có trong kho lưu trữ GitHub. Để bắt đầu, hãy lấy mã và mở nó trong môi trường phát triển yêu thích của bạn.
- Giải nén tệp zip đã tải xuống.
- Để cài đặt các phụ thuộc cần thiết, hãy mở terminal trong thư mục
functions
và chạy lệnhnpm install
.
Thiết lập căn cứ hỏa lực
Lớp học lập trình này đặc biệt khuyến khích việc sử dụng trình mô phỏng Firebase. Nếu bạn muốn thử phát triển tiện ích mở rộng bằng dự án Firebase thực, hãy xem cách tạo dự án Firebase . Lớp học lập trình này sử dụng Chức năng đám mây, vì vậy nếu đang sử dụng dự án Firebase thực thay vì trình mô phỏng, bạn cần nâng cấp lên gói giá Blaze .
Bạn muốn bỏ qua phía trước?
Bạn có thể tải xuống phiên bản hoàn chỉnh của lớp học lập trình. Nếu bạn gặp khó khăn trong quá trình thực hiện hoặc nếu bạn muốn xem một tiện ích mở rộng hoàn chỉnh trông như thế nào, hãy xem nhánh codelab-end
của kho lưu trữ GitHub hoặc tải xuống tệp zip hoàn chỉnh.
3. Xem lại mã
- Mở tệp
index.ts
từ tệp zip. Lưu ý rằng nó chứa hai khai báo Hàm đám mây bên trong.
Những chức năng này làm gì?
Các hàm demo này được sử dụng để băm địa lý. Họ lấy một cặp tọa độ và biến chúng thành định dạng được tối ưu hóa cho các truy vấn địa lý trong Firestore. Các hàm mô phỏng việc sử dụng lệnh gọi API để bạn có thể tìm hiểu thêm về cách xử lý các loại dữ liệu nhạy cảm trong tiện ích mở rộng. Để biết thêm thông tin, hãy xem tài liệu về cách chạy truy vấn Địa lý trên dữ liệu trong Firestore .
Hằng số hàm
Các hằng số được khai báo sớm, ở đầu tệp index.ts
. Một số hằng số này được tham chiếu trong trình kích hoạt được xác định của tiện ích mở rộng.
chỉ mục.ts
import {firestore} from "firebase-functions";
import {initializeApp} from "firebase-admin/app";
import {GeoHashService, ResultStatusCode} from "./fake-geohash-service";
import {onCall} from "firebase-functions/v1/https";
import {fieldValueExists} from "./utils";
const documentPath = "users/{uid}";
const xField = "xv";
const yField = "yv";
const apiKey = "1234567890";
const outputField = "hash";
initializeApp();
const service = new GeoHashService(apiKey);
Trình kích hoạt Firestore
Hàm đầu tiên trong tệp index.ts
trông như thế này:
chỉ mục.ts
export const locationUpdate = firestore.document(documentPath)
.onWrite((change) => {
// item deleted
if (change.after == null) {
return 0;
}
// double check that both values exist for computation
if (
!fieldValueExists(change.after.data(), xField) ||
!fieldValueExists(change.after.data(), yField)
) {
return 0;
}
const x: number = change.after.data()![xField];
const y: number = change.after.data()![yField];
const hash = service.convertToHash(x, y);
// This is to check whether the hash value has changed. If
// it hasn't, you don't want to write to the document again as it
// would create a recursive write loop.
if (fieldValueExists(change.after.data(), outputField)
&& change.after.data()![outputField] == hash) {
return 0;
}
return change.after.ref
.update(
{
[outputField]: hash.hash,
}
);
});
Chức năng này là một trình kích hoạt Firestore . Khi một sự kiện ghi xảy ra trong cơ sở dữ liệu, hàm sẽ phản ứng với sự kiện đó bằng cách tìm kiếm trường xv
và trường yv
, đồng thời, nếu cả hai trường đó tồn tại, hàm sẽ tính toán geohash và ghi kết quả đầu ra vào một vị trí đầu ra tài liệu được chỉ định. Tài liệu đầu vào được xác định bởi hằng số users/{uid}
, có nghĩa là hàm đọc mọi tài liệu được ghi vào users/
bộ sưu tập và sau đó xử lý một geohash cho những tài liệu đó. Sau đó, nó xuất hàm băm thành trường băm trong cùng một tài liệu.
Chức năng có thể gọi được
Hàm tiếp theo trong tệp index.ts
trông như thế này:
chỉ mục.ts
export const callableHash = onCall((data, context) => {
if (context.auth == undefined) {
return {error: "Only authorized users are allowed to call this endpoint"};
}
const x = data[xField];
const y = data[yField];
if (x == undefined || y == undefined) {
return {error: "Either x or y parameter was not declared"};
}
const result = service.convertToHash(x, y);
if (result.status != ResultStatusCode.ok) {
return {error: `Something went wrong ${result.message}`};
}
return {result: result.hash};
});
Hãy chú ý đến hàm onCall
. Nó chỉ ra rằng hàm này là một hàm có thể gọi được , có thể được gọi từ bên trong mã ứng dụng khách của bạn. Hàm có thể gọi này nhận các tham số x
và y
và trả về một geohash. Mặc dù hàm này sẽ không được gọi trực tiếp trong lớp học lập trình này nhưng nó được đưa vào đây làm ví dụ về nội dung cần định cấu hình trong tiện ích Firebase.
4. Thiết lập file mở rộng.yaml
Bây giờ bạn đã biết mã Chức năng đám mây trong tiện ích mở rộng của mình làm gì, bạn đã sẵn sàng đóng gói để phân phối. Mỗi tiện ích mở rộng Firebase đều đi kèm với tệp extension.yaml
mô tả chức năng và cách thức hoạt động của tiện ích mở rộng.
Tệp tiện ích extension.yaml
yêu cầu một số siêu dữ liệu ban đầu về tiện ích mở rộng của bạn. Mỗi bước sau đây sẽ giúp bạn hiểu ý nghĩa của tất cả các trường và lý do bạn cần chúng.
- Tạo tệp
extension.yaml
trong thư mục gốc của dự án mà bạn đã tải xuống trước đó. Bắt đầu bằng cách thêm vào như sau:
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
Tên của tiện ích mở rộng được sử dụng làm cơ sở cho ID phiên bản của tiện ích mở rộng (người dùng có thể cài đặt nhiều phiên bản của tiện ích mở rộng, mỗi phiên bản có ID riêng). Sau đó, Firebase tạo tên tài khoản dịch vụ của tiện ích mở rộng và tài nguyên dành riêng cho tiện ích mở rộng bằng ID phiên bản đó. Số phiên bản cho biết phiên bản tiện ích mở rộng của bạn. Nó phải tuân theo phiên bản ngữ nghĩa và bạn cần cập nhật nó bất cứ khi nào bạn thực hiện thay đổi đối với chức năng của tiện ích mở rộng. Phiên bản thông số tiện ích mở rộng được sử dụng để xác định thông số tiện ích mở rộng Firebase nào sẽ tuân theo, trong trường hợp này, v1beta
được sử dụng.
- Thêm một số chi tiết thân thiện với người dùng vào tệp YAML:
...
displayName: Latitude and longitude to GeoHash converter
description: A converter for changing your Latitude and longitude coordinates to geohashes.
Tên hiển thị là sự thể hiện thân thiện với tên tiện ích mở rộng của bạn khi nhà phát triển tương tác với tiện ích mở rộng của bạn. Mô tả cung cấp tổng quan ngắn gọn về chức năng của tiện ích mở rộng. Khi tiện ích mở rộng được triển khai trên Extensions.dev , nó trông giống như thế này:
- Chỉ định giấy phép cho mã trong tiện ích mở rộng của bạn.
...
license: Apache-2.0 # The license you want for the extension
- Cho biết ai đã viết tiện ích mở rộng và có cần thanh toán để cài đặt tiện ích mở rộng hay không:
...
author:
authorName: AUTHOR_NAME
url: https://github.com/Firebase
billingRequired: true
Phần author
được sử dụng để cho phép người dùng của bạn biết cần liên hệ với ai trong trường hợp họ gặp sự cố với tiện ích mở rộng hoặc muốn biết thêm thông tin về tiện ích mở rộng đó. billingRequired
là tham số bắt buộc và phải được đặt thành true
vì tất cả tiện ích mở rộng đều dựa vào Cloud Functions, yêu cầu gói Blaze.
Điều này bao gồm số lượng trường tối thiểu bắt buộc trong tệp extension.yaml
để xác định tiện ích mở rộng này. Để biết thêm chi tiết về thông tin nhận dạng khác mà bạn có thể chỉ định trong tiện ích mở rộng, hãy xem tài liệu .
5. Chuyển đổi mã Chức năng đám mây thành tài nguyên Tiện ích mở rộng
Tài nguyên tiện ích mở rộng là một mục mà Firebase tạo trong dự án trong quá trình cài đặt tiện ích mở rộng. Sau đó, tiện ích mở rộng sở hữu các tài nguyên đó và có tài khoản dịch vụ cụ thể hoạt động trên chúng. Trong dự án này, các tài nguyên đó là Cloud Functions, tài nguyên này phải được xác định trong tệp extension.yaml
vì tiện ích mở rộng sẽ không tự động tạo tài nguyên từ mã trong thư mục hàm. Nếu Chức năng đám mây của bạn không được khai báo rõ ràng dưới dạng tài nguyên thì chúng không thể được triển khai khi tiện ích mở rộng được triển khai.
Vị trí triển khai do người dùng xác định
- Cho phép người dùng chỉ định vị trí nơi họ muốn triển khai tiện ích mở rộng này và quyết định xem nên lưu trữ tiện ích mở rộng gần người dùng cuối hơn hay gần cơ sở dữ liệu của họ hơn. Trong tệp
extension.yaml
, hãy bao gồm tùy chọn để chọn vị trí.
phần mở rộng.yaml
Bây giờ bạn đã sẵn sàng viết cấu hình cho tài nguyên hàm.
- Trong tệp
extension.yaml
, tạo một đối tượng tài nguyên cho hàmlocationUpdate
. Nối phần sau vào tệpextension.yaml
:
resources:
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}
Bạn xác định name
là tên hàm được xác định trong tệp index.ts
của dự án. Bạn chỉ định type
chức năng đang được triển khai, hiện tại, loại chức năng này phải luôn là firebaseextensions.v1beta.function
. Sau đó, bạn xác định properties
của hàm này. thuộc tính đầu tiên bạn xác định là eventTrigger
được liên kết với hàm này. Để phản ánh những gì tiện ích mở rộng hiện hỗ trợ, bạn sử dụng eventType
của providers/cloud.firestore/eventTypes/document.write
, được tìm thấy trong Chức năng ghi đám mây cho tài liệu tiện ích mở rộng của bạn . Bạn xác định resource
là vị trí của tài liệu. Vì mục tiêu hiện tại của bạn là phản chiếu những gì tồn tại trong mã nên đường dẫn tài liệu sẽ lắng nghe users/{uid}
, với vị trí cơ sở dữ liệu mặc định trước nó.
- Tiện ích mở rộng cần có quyền đọc và ghi đối với cơ sở dữ liệu Firestore. Ở cuối tệp
extension.yaml
, hãy chỉ định vai trò IAM mà tiện ích mở rộng có quyền truy cập để hoạt động với cơ sở dữ liệu trong dự án Firebase của nhà phát triển.
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
Vai trò datastore.user
xuất phát từ danh sách vai trò IAM được hỗ trợ cho tiện ích mở rộng . Vì tiện ích mở rộng sẽ đọc và ghi nên vai trò datastore.user
rất phù hợp ở đây.
- Chức năng có thể gọi được cũng phải được thêm vào. Trong tệp
extension.yaml
, tạo một tài nguyên mới trong thuộc tính tài nguyên. Các thuộc tính này dành riêng cho một hàm có thể gọi được:
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
Mặc dù tài nguyên trước đó sử dụng eventTrigger
, nhưng ở đây bạn sử dụng httpsTrigger
, bao gồm cả hàm có thể gọi và hàm HTTPS.
Kiểm tra mã
Cần rất nhiều cấu hình để làm cho extension.yaml
của bạn khớp với mọi thứ được thực hiện bằng mã trong tệp index.ts
của bạn. Tệp extension.yaml
đã hoàn thành sẽ trông như thế này vào thời điểm này:
phần mở rộng.yaml
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
displayName: Latitude and Longitude to GeoHash converter
description: A converter for changing your Latitude and Longitude coordinates to geohashes.
license: Apache-2.0 # The license you want for the extension
author:
authorName: Sparky
url: https://github.com/Firebase
billingRequired: true
resources:
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
Kiểm tra tình trạng
Tại thời điểm này, bạn đã thiết lập các phần chức năng ban đầu của tiện ích mở rộng, vì vậy bạn thực sự có thể dùng thử nó bằng trình mô phỏng Firebase!
- Nếu bạn chưa làm vậy, hãy gọi
npm run build
trong thư mục chức năng của dự án tiện ích mở rộng đã tải xuống. - Tạo một thư mục mới trên hệ thống máy chủ của bạn và kết nối thư mục đó với dự án Firebase của bạn bằng
firebase init
.
cd .. mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
This command creates a `firebase.json` file in the directory. In the following steps, you push the configuration specified in this file to Firebase.
- Từ cùng thư mục, chạy
firebase ext:install
. Thay thế/path/to/extension
bằng đường dẫn tuyệt đối đến thư mục chứa tệpextension.yaml
của bạn.
firebase ext:install /path/to/extension
This command does two things:
- Nó nhắc bạn chỉ định cấu hình cho phiên bản tiện ích mở rộng và nó tạo một tệp
*.env
chứa thông tin cấu hình cho phiên bản đó. - Nó thêm phiên bản tiện ích mở rộng vào phần
extensions
củafirebase.json
của bạn. Điều này hoạt động như một bản đồ ID phiên bản tới phiên bản tiện ích mở rộng. - Vì bạn đang triển khai dự án cục bộ nên bạn có thể chỉ định rằng bạn muốn sử dụng tệp cục bộ thay vì Trình quản lý bí mật của Google Cloud.
- Khởi động trình giả lập Firebase với cấu hình mới:
firebase emulators:start
- Sau khi chạy
emulators:start
, hãy điều hướng đến tab Firestore trong chế độ xem web của trình mô phỏng. - Thêm tài liệu vào bộ sưu tập
users
với trường sốxv
và trường sốyv
.
- Nếu bạn cài đặt thành công tiện ích mở rộng, tiện ích mở rộng sẽ tạo một trường mới gọi là
hash
trong tài liệu.
Dọn dẹp để tránh xung đột
- Sau khi kiểm tra xong, hãy gỡ cài đặt tiện ích mở rộng—bạn sẽ cập nhật mã tiện ích mở rộng và không muốn xung đột với tiện ích mở rộng hiện tại sau này.
Tiện ích mở rộng cho phép cài đặt nhiều phiên bản của cùng một tiện ích mở rộng cùng một lúc, do đó, bằng cách gỡ cài đặt, bạn đảm bảo rằng không có xung đột với tiện ích mở rộng đã cài đặt trước đó.
firebase ext:uninstall geohash-ext
Giải pháp hiện tại hoạt động nhưng như đã đề cập ở phần đầu của dự án, có một khóa API được mã hóa cứng để mô phỏng giao tiếp với một dịch vụ. Làm cách nào bạn có thể sử dụng khóa API của người dùng cuối thay vì khóa API được cung cấp ban đầu? Đọc để tìm hiểu.
6. Làm cho người dùng tiện ích mở rộng có thể cấu hình được
Tại thời điểm này trong lớp học lập trình, bạn có một tiện ích mở rộng được định cấu hình để sử dụng với thiết lập theo ý kiến của các hàm mà bạn đã viết, nhưng điều gì sẽ xảy ra nếu người dùng của bạn muốn sử dụng vĩ độ và kinh độ thay vì y và x cho các trường biểu thị vị trí trên mặt phẳng Descartes? Ngoài ra, làm cách nào bạn có thể yêu cầu người dùng cuối cung cấp khóa API của riêng họ thay vì để họ sử dụng khóa API được cung cấp? Bạn có thể nhanh chóng vượt quá hạn ngạch cho API đó. Trong trường hợp này, bạn thiết lập và sử dụng các tham số.
Xác định các tham số cơ bản trong file extension.yaml
Bắt đầu bằng cách chuyển đổi các mục mà nhà phát triển có thể có cấu hình tùy chỉnh. Đầu tiên sẽ là tham số XFIELD
và YFIELD
.
- Trong tệp
extension.yaml
, thêm mã sau, sử dụng tham số trườngXFIELD
vàYFIELD
. Các tham số này nằm bên trong thuộc tính YAMLparams
được xác định trước đó:
phần mở rộng.yaml
params:
- param: XFIELD
label: The X Field Name
description: >-
The X Field is also known as the **longitude** value. What does
your Firestore instance refer to as the X value or the longitude
value. If no value is specified, the extension searches for
field 'xv'.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: xv
required: false
immutable: false
example: xv
- param: YFIELD
label: The Y Field Name
description: >-
The Y Field is also known as the **latitude** value. What does
your Firestore instance refer to as the Y value or the latitude
value. If no value is specified, the extension searches for
field 'yv'.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: yv
required: false
immutable: false
example: yv
- param đặt tên tham số theo cách mà bạn, nhà sản xuất tiện ích mở rộng, có thể nhìn thấy. Sử dụng giá trị này sau này khi chỉ định các giá trị tham số.
- nhãn là mã định danh mà con người có thể đọc được đối với nhà phát triển để cho họ biết tham số đó làm gì.
- mô tả cung cấp một mô tả chi tiết về giá trị. Vì điều này hỗ trợ đánh dấu nên nó có thể liên kết đến tài liệu bổ sung hoặc có thể đánh dấu các từ có thể quan trọng đối với nhà phát triển.
- type xác định cơ chế đầu vào về cách người dùng đặt giá trị tham số. Có nhiều loại tồn tại, bao gồm
string
,select
,multiSelect
,selectResource
vàsecret
. Để tìm hiểu thêm về từng tùy chọn này, hãy xem tài liệu . - validationRegex ràng buộc mục nhập của nhà phát triển ở một giá trị biểu thức chính quy nhất định (trong ví dụ này, nó dựa trên các nguyên tắc tên trường đơn giản được tìm thấy ở đây ); và nếu thất bại...
- validationErrorMessage cảnh báo cho nhà phát triển về giá trị lỗi.
- mặc định là giá trị sẽ như thế nào nếu nhà phát triển không nhập bất kỳ văn bản nào.
- bắt buộc có nghĩa là nhà phát triển không bắt buộc phải nhập bất kỳ văn bản nào.
- bất biến cho phép nhà phát triển cập nhật tiện ích mở rộng này và thay đổi giá trị này. Trong trường hợp này, nhà phát triển có thể thay đổi tên trường khi yêu cầu của họ thay đổi.
- ví dụ này cung cấp ý tưởng về đầu vào hợp lệ sẽ trông như thế nào.
Đó là rất nhiều điều để hiểu!
- Bạn có thêm ba tham số để thêm vào tệp
extension.yaml
trước khi thêm một tham số đặc biệt.
- param: INPUTPATH
label: The input document to listen to for changes
description: >-
This is the document where you write an x and y value to. Once
that document has received a value, it notifies the extension to
calculate a geohash and store that in an output document in a certain
field. This accepts function [wildcard parameters](https://firebase.google.com/docs/functions/firestore-events#wildcards-parameters)
type: string
validationRegex: ^[^/]+(/[^/]*/[^/]*)*/[^/]+$
validationErrorMessage: >-
This must point to a document path, not a collection path from the root
of the database. It must also not start or end with a '/' character.
required: true
immutable: false
example: users/{uid}
- param: OUTPUTFIELD
label: Geohash field
description: >-
This specifies the field in the output document to store the geohash in.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
required: false
default: hash
immutable: false
example: hash
Xác định các thông số nhạy cảm
Bây giờ, bạn cần quản lý khóa API mà người dùng chỉ định. Đây là một chuỗi nhạy cảm không được lưu trữ ở dạng văn bản thuần túy trong hàm. Thay vào đó, hãy lưu trữ giá trị này trong Trình quản lý bí mật của Đám mây . Đây là một vị trí đặc biệt trên đám mây lưu trữ các bí mật được mã hóa và ngăn chúng vô tình bị rò rỉ. Điều này yêu cầu nhà phát triển phải trả tiền cho việc sử dụng dịch vụ này nhưng nó bổ sung thêm một lớp bảo mật cho các khóa API của họ và có khả năng hạn chế hoạt động gian lận. Tài liệu dành cho người dùng cảnh báo nhà phát triển rằng đây là dịch vụ phải trả phí, do đó không có bất kỳ điều gì bất ngờ trong việc thanh toán. Nhìn chung, cách sử dụng cũng tương tự như các tài nguyên chuỗi khác được đề cập ở trên. Sự khác biệt duy nhất là loại được gọi là secret
.
- Trong tệp
extension.yaml
, thêm đoạn mã sau:
phần mở rộng.yaml
- param: APIKEY
label: GeohashService API Key
description: >-
Your geohash service API Key. Since this is a demo, and not a real
service, you can use : 1234567890.
type: secret
required: true
immutable: false
Cập nhật thuộc tính resource
để sử dụng tham số
Như đã đề cập trước đó, tài nguyên (không phải hàm) xác định cách quan sát tài nguyên, do đó tài nguyên locationUpdate
cần được cập nhật để sử dụng tham số mới.
- Trong tệp
extension.yaml
, thêm đoạn mã sau:
phần mở rộng.yaml
## Change from this
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}]
## To this
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/${INPUTPATH}
Kiểm tra tệp extension.yaml
- Xem lại tệp
extension.yaml
. Nó sẽ trông giống như thế này:
phần mở rộng.yaml
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
displayName: Latitude and Longitude to GeoHash converter
description: A converter for changing your Latitude and Longitude coordinates to geohashes.
license: Apache-2.0 # The license you want to use for the extension
author:
authorName: Sparky
url: https://github.com/Firebase
billingRequired: true
params:
- param: XFIELD
label: The X Field Name
description: >-
The X Field is also known as the **longitude** value. What does
your Firestore instance refer to as the X value or the longitude
value. If you don't provide a value for this field, the extension will use 'xv' as the default value.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: xv
required: false
immutable: false
example: xv
- param: YFIELD
label: The Y Field Name
description: >-
The Y Field is also known as the **latitude** value. What does
your Firestore instance refer to as the Y value or the latitude
Value. If you don't provide a value for this field, the extension will use 'yv' as the default value.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: yv
required: false
immutable: false
example: yv
- param: INPUTPATH
label: The input document to listen to for changes
description: >-
This is the document where you write an x and y value to. Once
that document has been modified, it notifies the extension to
compute a geohash and store that in an output document in a certain
field. This accepts function [wildcard parameters](https://firebase.google.com/docs/functions/firestore-events#wildcards-parameters)
type: string
validationRegex: ^[^/]+(/[^/]*/[^/]*)*/[^/]+$
validationErrorMessage: >-
This must point to a document path, not a collection path from the root
of the database. It must also not start or end with a '/' character.
required: true
immutable: false
example: users/{uid}
- param: OUTPUTFIELD
label: Geohash field
description: >-
This specifies the field in the output document to store the geohash in.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
required: false
default: hash
immutable: false
example: hash
- param: APIKEY
label: GeohashService API Key
description: >-
Your geohash service API Key. Since this is a demo, and not a real
service, you can use : 1234567890.
type: secret
required: true
immutable: false
resources:
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/${INPUTPATH}
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
Truy cập các tham số trong mã
Bây giờ tất cả các tham số đã được định cấu hình trong tệp extension.yaml
, hãy thêm chúng vào tệp index.ts
.
- Trong tệp
index.ts
, hãy thay thế các giá trị mặc định bằngprocess.env.PARAMETER_NAME
để tìm nạp các giá trị tham số thích hợp và điền chúng vào mã chức năng được triển khai trên dự án Firebase của nhà phát triển.
chỉ mục.ts
// Replace this:
const documentPath = "users/{uid}";
const xField = "xv";
const yField = "yv";
const apiKey = "1234567890";
const outputField = "hash";
// with this:
const documentPath = process.env.INPUTPATH!; // this value is ignored since its read from the resource
const xField = process.env.XFIELD!;
const yField = process.env.YFIELD!;
const apiKey = process.env.APIKEY!;
const outputField = process.env.OUTPUTFIELD!;
Thông thường, bạn muốn thực hiện kiểm tra null với các giá trị biến môi trường, nhưng trong trường hợp này, bạn tin tưởng rằng các giá trị tham số được sao chép chính xác. Mã hiện được cấu hình để hoạt động với các tham số mở rộng.
7. Tạo tài liệu người dùng
Trước khi thử nghiệm mã trên trình mô phỏng hoặc trên thị trường tiện ích mở rộng Firebase, tiện ích mở rộng cần phải được ghi lại để nhà phát triển biết họ sẽ nhận được gì khi sử dụng tiện ích mở rộng.
- Bắt đầu bằng cách tạo tệp
PREINSTALL.md
, tệp này được sử dụng để mô tả chức năng, mọi điều kiện tiên quyết để cài đặt và các tác động thanh toán tiềm ẩn.
PREINSTALL.md
Use this extension to automatically convert documents with a latitude and
longitude to a geohash in your database. Additionally, this extension includes a callable function that allows users to make one-time calls
to convert an x,y coordinate into a geohash.
Geohashing is supported for latitudes between 90 and -90 and longitudes
between 180 and -180.
#### Third Party API Key
This extension uses a fictitious third-party API for calculating the
geohash. You need to supply your own API keys. (Since it's fictitious,
you can use 1234567890 as an API key).
#### Additional setup
Before installing this extension, make sure that you've [set up a Cloud
Firestore database](https://firebase.google.com/docs/firestore/quickstart) in your Firebase project.
After installing this extension, you'll need to:
- Update your client code to point to the callable geohash function if you
want to perform arbitrary geohashes.
Detailed information for these post-installation tasks are provided after
you install this extension.
#### 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:
- Cloud Firestore
- Cloud Functions (Node.js 16+ runtime. [See
FAQs](https://firebase.google.com/support/faq#extensions-pricing))
- [Cloud Secret Manager](https://cloud.google.com/secret-manager/pricing)
- Để tiết kiệm thời gian viết
README.md
cho dự án này, hãy sử dụng phương pháp tiện lợi:
firebase ext:info . --markdown > README.md
Điều này kết hợp nội dung của tệp PREINSTALL.md
và các chi tiết bổ sung về tiện ích mở rộng từ tệp extension.yaml
của bạn.
Cuối cùng, hãy thông báo cho nhà phát triển tiện ích mở rộng về một số chi tiết bổ sung liên quan đến tiện ích mở rộng vừa được cài đặt. Nhà phát triển có thể nhận được một số hướng dẫn và thông tin bổ sung sau khi hoàn tất quá trình cài đặt và có thể nhận được một số tác vụ chi tiết sau khi cài đặt như thiết lập mã máy khách tại đây.
- Tạo tệp
POSTINSTALL.md
, sau đó bao gồm thông tin cài đặt bài đăng sau:
POSTINSTALL.md
Congratulations on installing the geohash extension!
#### Function information
* **Firestore Trigger** - ${function:locationUpdate.name} was installed
and is invoked when both an x field (${param:XFIELD}) and y field
(${param:YFIELD}) contain a value.
* **Callable Trigger** - ${function:callableHash.name} was installed and
can be invoked by writing the following client code:
```javascript
import { getFunctions, httpsCallable } from "firebase/functions";
const functions = getFunctions();
const geoHash = httpsCallable(functions, '${function:callableHash.name}');
geoHash({ ${param:XFIELD}: -122.0840, ${param:YFIELD}: 37.4221 })
.then((result) => {
// Read result of the Cloud Function.
/** @type {any} */
const data = result.data;
const error = data.error;
if (error != null) {
console.error(`callable error : ${error}`);
}
const result = data.result;
console.log(result);
});
Giám sát
Cách tốt nhất là bạn có thể giám sát hoạt động của tiện ích mở rộng đã cài đặt của mình, bao gồm kiểm tra tình trạng, mức sử dụng và nhật ký của tiện ích mở rộng đó.
The output rendering looks something like this when it's deployed:
<img src="img/82b54a5c6ca34b3c.png" alt="A preview of the latitude and longitude geohash converter extension in the firebase console" width="957.00" />
## Test the extension with the full configuration
Duration: 03:00
It's time to make sure that the user-configurable extension is working the way it is intended.
* Change into the functions folder and ensure that the latest compiled version of the extensions exists. In the extensions project functions directory, call:
```console
npm run build
Việc này sẽ biên dịch lại các chức năng để mã nguồn mới nhất sẵn sàng triển khai cùng với tiện ích mở rộng khi nó được triển khai trực tiếp vào trình mô phỏng hoặc tới Firebase.
Tiếp theo, tạo một thư mục mới để kiểm tra tiện ích mở rộng. Vì tiện ích mở rộng được phát triển từ các chức năng hiện có nên không kiểm tra từ thư mục chứa tiện ích mở rộng được định cấu hình vì thư mục đó cũng cố gắng triển khai các chức năng và quy tắc Firebase cùng với nó.
Cài đặt và thử nghiệm với trình giả lập Firebase
- Tạo một thư mục mới trên hệ thống máy chủ của bạn và kết nối thư mục đó với dự án Firebase của bạn bằng
firebase init
.
mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- Từ thư mục đó, hãy chạy
firebase ext:install
để cài đặt tiện ích mở rộng. Thay thế/path/to/extension
bằng đường dẫn tuyệt đối đến thư mục chứa tệpextension.yaml
của bạn. Thao tác này sẽ bắt đầu quá trình cài đặt tiện ích mở rộng của bạn và tạo tệp.env
chứa cấu hình của bạn trước khi đẩy cấu hình sang Firebase hoặc trình mô phỏng.
firebase ext:install /path/to/extension
- Vì bạn đang triển khai dự án cục bộ, hãy chỉ định rằng bạn muốn sử dụng tệp cục bộ thay vì Trình quản lý bí mật của Google Cloud.
- Bắt đầu bộ mô phỏng cục bộ:
firebase emulators:start
Cài đặt và thử nghiệm với dự án Firebase thực sự
Bạn có thể cài đặt tiện ích mở rộng của mình trong dự án Firebase thực tế. Bạn nên sử dụng một dự án thử nghiệm để thử nghiệm. Sử dụng quy trình kiểm tra này nếu bạn muốn kiểm tra luồng từ đầu đến cuối của tiện ích mở rộng hoặc nếu trình kích hoạt tiện ích mở rộng của bạn chưa được bộ mô phỏng Firebase hỗ trợ (xem tùy chọn Trình mô phỏng tiện ích mở rộng ). Trình mô phỏng hiện hỗ trợ các hàm kích hoạt yêu cầu HTTP và các hàm kích hoạt sự kiện nền cho Cloud Firestore, Cơ sở dữ liệu thời gian thực và Pub/Sub.
- Tạo một thư mục mới trên hệ thống máy chủ của bạn và kết nối thư mục đó với dự án Firebase của bạn bằng
firebase init
.
cd .. mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- Sau đó, từ thư mục đó, hãy chạy
firebase ext:install
để cài đặt tiện ích mở rộng. Thay thế/path/to/extension
bằng đường dẫn tuyệt đối đến thư mục chứa tệpextension.yaml
của bạn. Thao tác này sẽ bắt đầu quá trình cài đặt tiện ích mở rộng của bạn và tạo tệp.env
chứa cấu hình của bạn trước khi đẩy cấu hình sang Firebase hoặc trình mô phỏng.
firebase ext:install /path/to/extension
- Vì bạn muốn triển khai trực tiếp lên Firebase và muốn sử dụng Google Cloud Secret Manager, bạn cần kích hoạt API Secret Manager trước khi cài đặt tiện ích mở rộng.
- Triển khai vào dự án Firebase của bạn.
firebase deploy
Kiểm tra phần mở rộng
- Sau khi chạy
firebase deploy
hoặcfirebase emulators:start
, hãy điều hướng đến tab Firestore của bảng điều khiển Firebase hoặc chế độ xem web của trình mô phỏng, nếu thích hợp. - Thêm tài liệu vào bộ sưu tập được chỉ định bởi trường
x
và trườngy
. Trong trường hợp này, các tài liệu cập nhật được đặt tạiu/{uid}
với trườngx
làxv
và trườngy
làyv
.
- Nếu bạn cài đặt thành công tiện ích mở rộng, tiện ích mở rộng sẽ tạo một trường mới gọi là
hash
trong tài liệu sau khi bạn lưu hai trường.
8. Xin chúc mừng!
Bạn đã chuyển đổi thành công Chức năng đám mây đầu tiên của mình thành Tiện ích mở rộng Firebase!
Bạn đã thêm tệp extension.yaml
và định cấu hình tệp đó để các nhà phát triển có thể chọn cách họ muốn triển khai tiện ích mở rộng của bạn. Sau đó, bạn đã tạo tài liệu dành cho người dùng cung cấp hướng dẫn về những gì nhà phát triển tiện ích mở rộng nên làm trước khi thiết lập tiện ích mở rộng và những bước họ có thể cần thực hiện sau khi cài đặt thành công tiện ích mở rộng.
Bây giờ bạn đã biết các bước chính cần thiết để chuyển đổi Hàm Firebase thành Tiện ích mở rộng Firebase có thể phân phối.