1. לפני שמתחילים
תוסף ל-Firebase מבצע משימה ספציפית או קבוצה של משימות בתגובה לבקשות HTTP או לאירועים שמופעלים ממוצרים אחרים של Firebase ו-Google, כמו Firebase Cloud Messaging, Cloud Firestore או Pub/Sub.
מה תפַתחו
ב-Codelab הזה, בונים תוסף של Firebase ל-geohashing. לאחר הפריסה, התוסף ממיר קואורדינטות X ו-Y ל-geohash בתגובה לאירועים ב-Firestore או באמצעות הפעלות של פונקציות שניתן לקרוא להן. אפשר להשתמש באפשרות הזו כחלופה להטמעת ספריית GeoFire בכל פלטפורמות היעד שלכם לאחסון נתונים, וכך לחסוך זמן.
מה תלמדו
- איך לוקחים קוד קיים של Cloud Functions והופכים אותו לתוסף Firebase שניתן להפצה
- איך מגדירים קובץ
extension.yaml
- איך מאחסנים מחרוזות רגישות (מפתחות API) בתוסף
- איך לאפשר למפתחים של התוסף להגדיר אותו כך שיתאים לצרכים שלהם
- איך בודקים ומפרסים את התוסף
מה צריך להכין
- Firebase CLI (התקנה והתחברות)
- חשבון Google, למשל חשבון Gmail.
- Node.js ו-
npm
- סביבת הפיתוח המועדפת עליכם
2. ליצירת קמפיין
קבלת הקוד
כל מה שצריך בשביל התוסף הזה נמצא במאגר ב-GitHub. כדי להתחיל, צריך להוריד את הקוד ולפתוח אותו בסביבת הפיתוח המועדפת עליכם.
- פותחים את קובץ ה-ZIP שהורדתם.
- כדי להתקין את יחסי התלות הנדרשים, פותחים את הטרמינל בספרייה
functions
ומריצים את הפקודהnpm install
.
מגדירים את Firebase
מומלץ מאוד להשתמש במהכלי ההדמיה של Firebase במסגרת הקודלאב הזה. אם אתם רוצים להתנסות בפיתוח תוספים בפרויקט Firebase אמיתי, קראו את המאמר יצירת פרויקט Firebase. ה-Codelab הזה משתמש ב-Cloud Functions, לכן אם אתם משתמשים בפרויקט Firebase אמיתי במקום באמולטורים, צריך לשדרג לתוכנית התמחור של Blaze.
רוצה לדלג קדימה?
אפשר להוריד גרסה מלאה של ה-Codelab. אם נתקעים בדרך או רוצים לראות איך נראה תוסף שהושלם, תוכלו לבדוק את ההסתעפות codelab-end
במאגר GitHub או להוריד את קובץ ה-ZIP שהושלם.
3. בדיקת הקוד
- פותחים את הקובץ
index.ts
מקובץ ה-zip. שימו לב שהוא מכיל שתי הצהרות של Cloud Functions.
למה הפונקציות האלה עושות?
פונקציות ההדגמה האלה משמשות לביצוע גיבוב (hashing) גיאוגרפי. הם לוקחים צמד קואורדינטות והופכים אותם לפורמט שמותאם לשאילתות גיאוגרפיות ב-Firestore. הפונקציות מדמות את השימוש בקריאה ל-API, כדי שתוכלו לקבל מידע נוסף על טיפול בסוגים של מידע אישי רגיש בתוספים. מידע נוסף זמין במאמר הרצת שאילתות גיאוגרפיות על נתונים ב-Firestore.
קבועי פונקציות
קבועים מוצהרים בשלב מוקדם, בחלק העליון של הקובץ index.ts
. יש הפניות לחלק מהקבועים האלה בטריגרים המוגדרים של התוסף.
index.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);
טריגר של Firestore
הפונקציה הראשונה בקובץ index.ts
נראית כך:
index.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,
}
);
});
הפונקציה הזו היא Firestore trigger. כשאירוע כתיבת נתונים מתרחש במסד הנתונים, הפונקציה מגיבה לאירוע הזה על ידי חיפוש של שדה xv
ושדה yv
. אם שני השדות האלה קיימים, היא מחשבת את ה-geohash ומזינה את הפלט במיקום הפלט שצוין למסמך. מסמך הקלט מוגדר על ידי הקבוע users/{uid}
, כלומר הפונקציה קוראת כל מסמך שנכתב באוסף users/
ולאחר מכן מעבדת גיבוב גיאוגרפי עבור המסמכים האלה. לאחר מכן, הוא יפיק את הגיבוב לשדה גיבוב (hash) באותו מסמך.
פונקציות שניתן להפעיל
הפונקציה הבאה בקובץ index.ts
נראית כך:
index.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};
});
שימו לב לפונקציה onCall
. הוא מציין שהפונקציה הזו היא פונקציה שניתן להפעיל, שאפשר להפעיל אותה מתוך הקוד של אפליקציית הלקוח. הפונקציה הניתנת לקריאה מקבלת את הפרמטרים x
ו-y
ומחזירה geohash. הפונקציה הזו לא תיקרא ישירות ב-codelab הזה, אבל היא כלולה כאן כדוגמה למשהו שצריך להגדיר בתוסף של Firebase.
4. הגדרת קובץ extension.yaml
עכשיו, אחרי שהבנתם מה הקוד של Cloud Functions בתוסף עושה, אתם מוכנים לארוז אותו ולהפיץ אותו. כל תוסף של Firebase מגיע עם קובץ extension.yaml
שמתאר את הפעולות של התוסף ואת האופן שבו הוא פועל.
בקובץ extension.yaml
נדרשים מטא-נתונים ראשוניים על התוסף. כל אחד מהשלבים הבאים יעזור לכם להבין את המשמעות של כל השדות ולמה אתם צריכים אותם.
- יוצרים קובץ
extension.yaml
בתיקיית השורש של הפרויקט שהורדתם קודם. מתחילים בהוספת הפרטים הבאים:
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
השם של התוסף משמש כבסיס למזהה המופע של התוסף (משתמשים יכולים להתקין כמה מופעים של תוסף, לכל אחד מהם מזהה משלו). לאחר מכן, מערכת Firebase יוצרת את השם של חשבונות השירות של התוסף ואת המשאבים הספציפיים לתוסף באמצעות מזהה המכונה הזה. מספר הגרסה מציין את גרסת התוסף. התוסף צריך להתאים לניהול גרסאות סמנטי, וצריך לעדכן אותו בכל פעם שמבצעים שינויים בפונקציונליות של התוסף. גרסת מפרט התוסף משמשת כדי לקבוע אחרי איזה מפרט תוספים ל-Firebase לפעול, במקרה הזה, ייעשה שימוש ב-v1beta
.
- מוסיפים לקובץ YAML פרטים ידידותיים למשתמש:
...
displayName: Latitude and longitude to GeoHash converter
description: A converter for changing your Latitude and longitude coordinates to geohashes.
השם המוצג מייצג בצורה ידידותית את שם התוסף בזמן האינטראקציה של מפתחים עם התוסף. התיאור מספק סקירה כללית קצרה של הפעולות שהתוסף מבצע. כשהתוסף נפרס ב-extensions.dev, הוא נראה בערך כך:
- מציינים את הרישיון לקוד בתוסף.
...
license: Apache-2.0 # The license you want for the extension
- מציינים מי כתב את התוסף ואם נדרש חיוב כדי להתקין אותו:
...
author:
authorName: AUTHOR_NAME
url: https://github.com/Firebase
billingRequired: true
הקטע author
משמש כדי להודיע למשתמשים למי לפנות במקרה של בעיות עם התוסף או אם הם רוצים לקבל מידע נוסף עליו. billingRequired
הוא פרמטר נדרש וצריך להגדיר אותו כ-true
, כי כל התוספים מסתמכים על Cloud Functions, שדורשת את תוכנית Blaze.
הערך הזה מציין את מספר השדות המינימלי שנדרש בקובץ extension.yaml
כדי לזהות את התוסף הזה. פרטים נוספים על פרטי זיהוי אחרים שאפשר לציין בתוסף זמינים במסמכי התיעוד.
5. המרת הקוד של Cloud Functions למשאב Extensions
משאב של תוסף הוא פריט שנוצר בפרויקט על ידי Firebase במהלך התקנת התוסף. לאחר מכן, המשאבים האלה יהיו בבעלות התוסף, ויהיו לו חשבון שירות ספציפי שפועל בהם. בפרויקט הזה, המשאבים האלה הם Cloud Functions, וצריך להגדיר אותם בקובץ extension.yaml
כי התוסף לא ייצור משאבים באופן אוטומטי מקוד בתיקיית הפונקציות. אם לא תצהירו במפורש על פונקציות Cloud כמשאבים, לא תוכלו לפרוס אותן כשתפרסו את התוסף.
מיקום פריסה שהוגדר על ידי המשתמש
- המשתמשים יכולים לציין את המיקום שבו הם רוצים לפרוס את התוסף ולהחליט אם עדיף לארח את התוסף קרוב יותר למשתמשי הקצה או קרוב יותר למסד הנתונים שלו. בקובץ
extension.yaml
, כוללים את האפשרות לבחור מיקום.
extension.yaml
עכשיו אפשר לכתוב את ההגדרות של משאב הפונקציה.
- בקובץ
extension.yaml
, יוצרים אובייקט משאב לפונקציהlocationUpdate
. יש להוסיף את הקטע הבא לקובץextension.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}
מגדירים את name
בתור שם הפונקציה שמוגדר בקובץ index.ts
של הפרויקט. מציינים את ה-type
של הפונקציה שנפרסת, שצריכה להיות תמיד firebaseextensions.v1beta.function
. לאחר מכן מגדירים את properties
של הפונקציה. הנכס הראשון שמגדירים הוא ה-eventTrigger
שמשויך לפונקציה הזו. כדי לשקף את התמיכה הנוכחית של התוסף, משתמשים ב-eventType
של providers/cloud.firestore/eventTypes/document.write
, שמופיע במסמך כתיבת פונקציות Cloud עבור התוסף. אתם מגדירים את resource
כמיקום של המסמכים. מכיוון שהיעד הנוכחי שלכם הוא לשקף את מה שקיים בקוד, נתיב המסמך מאזין ל-users/{uid}
, ולפניו מופיע מיקום ברירת המחדל של מסד הנתונים.
- לתוסף נדרשות הרשאות קריאה וכתיבה למסד הנתונים של Firestore. בסוף הקובץ
extension.yaml
, מציינים את תפקידי ה-IAM שלגביהם לתוסף צריכה להיות גישה כדי לעבוד עם מסד הנתונים בפרויקט Firebase של המפתח.
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
התפקיד datastore.user
מגיע מרשימת תפקידי IAM נתמכים לתוספים. מכיוון שהתוסף מיועד לקריאה וכתיבה, התפקיד datastore.user
מתאים כאן.
- צריך להוסיף גם את הפונקציה שניתנת לקריאה. בקובץ
extension.yaml
, יוצרים משאב חדש במאפיין המשאבים. המאפיינים הבאים ספציפיים לפונקציה שניתן להתקשר אליה:
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
על אף שהמשאב הקודם השתמש ב-eventTrigger
, כאן משתמשים ב-httpsTrigger
, שמכסה גם פונקציות שניתן לקרוא וגם פונקציות HTTPS.
בדיקת הקוד
נדרשו הרבה הגדרות כדי לגרום ל-extension.yaml
להתאים לכל הפעולות בקוד שבקובץ index.ts
. קובץ extension.yaml
המלא אמור להיראות כך בשלב הזה:
extension.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.
בדיקת סטטוס
בשלב הזה, החלק הפונקציונלי הראשוני של התוסף מוגדר, כך שאפשר לנסות אותו באמצעות אמוללטורים של Firebase.
- אם עדיין לא עשיתם זאת, קוראים לפונקציה
npm run build
בתיקיית הפונקציות בפרויקט התוספים שהורדתם. - יוצרים ספרייה חדשה במערכת המארחת ומחברים אותה לפרויקט Firebase באמצעות
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.
- מאותה ספרייה, מריצים את
firebase ext:install
. מחליפים את/path/to/extension
בנתיב המוחלט לספרייה שמכילה את קובץextension.yaml
.
firebase ext:install /path/to/extension
This command does two things:
- תוצג בקשה לציין את ההגדרות למכונה של התוסף, וייווצר קובץ
*.env
שמכיל את פרטי ההגדרה של המכונה. - הוא מוסיף את מופע התוסף לקטע
extensions
ב-firebase.json
. הפעולה הזו משמשת כמפה של מזהה המכונה לגרסת התוסף. - מכיוון שאתם פורסים את הפרויקט באופן מקומי, אפשר לציין שאתם רוצים להשתמש בקובץ מקומי ולא ב-Google Cloud Secret Manager.
- מפעילים את האמולטורים של Firebase עם ההגדרה החדשה:
firebase emulators:start
- אחרי שמריצים את
emulators:start
, עוברים לכרטיסייה Firestore ב-WebView של האמולטורים. - מוסיפים מסמך לאוסף
users
עם שדה מספרxv
ושדה מספרyv
.
- אם ההתקנה של התוסף הושלמה, התוסף יוצר במסמך שדה חדש בשם
hash
.
ניקוי כדי למנוע התנגשויות
- אחרי שנסיים את הבדיקה, נצטרך להסיר את התוסף. אנחנו עומדים לעדכן את קוד התוסף, ולא רוצים שיהיה לו קונפליקט עם התוסף הנוכחי בשלב מאוחר יותר.
תוספים מאפשרים להתקין מספר גרסאות של אותו תוסף בו-זמנית, כך שהסרת ההתקנה תבטיח שאין התנגשויות עם תוסף שהותקן קודם לכן.
firebase ext:uninstall geohash-ext
הפתרון הנוכחי עובד, אבל כפי שציינו בתחילת הפרויקט, יש מפתח API בתוך הקוד שמטרתו לדמות תקשורת עם שירות. איך אפשר להשתמש במפתח ה-API של משתמש הקצה במקום במפתח שסופק במקור? כדאי לקרוא בהמשך כדי לגלות.
6. הגדרת המשתמש בתוסף
בשלב הזה ב-Codelab יש תוסף שמוגדר לשימוש עם ההגדרות המקובעות של הפונקציות שכבר כתבת. אבל מה אם המשתמש רוצה להשתמש בקווי אורך ורוחב במקום ב-y וב-x בשדות שמציינים את המיקום במישור קרטיאני? בנוסף, איך אפשר לגרום למשתמש הקצה לספק מפתח API משלו, במקום לאפשר לו לצרוך את מפתח ה-API שסופק? אתם עלולים לחרוג במהירות מהמכסה של ה-API הזה. במקרה כזה, מגדירים פרמטרים ומשתמשים בהם.
מגדירים פרמטרים בסיסיים בקובץ extension.yaml
בתור התחלה, צריך להמיר את הפריטים שלמפתחים יש אפשרות להגדיר עבורם הגדרות אישיות. הפרמטרים הראשונים הם XFIELD
ו-YFIELD
.
- בקובץ
extension.yaml
, מוסיפים את הקוד הבא, שמשתמש בפרמטר השדהXFIELD
ובפרמטר השדהYFIELD
. הפרמטרים האלה נמצאים בנכס YAMLparams
שהוגדר קודם לכן:
extension.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 נותן לפרמטר שם באופן שגלוי לכם, הבעלים של התוסף. יש להשתמש בערך הזה בהמשך, כאשר מציינים את ערכי הפרמטרים.
- label הוא מזהה קריא לאנשים בשביל המפתח, כדי שהוא יוכל לדעת מה הפרמטר עושה.
- description – תיאור מפורט של הערך. הפעולה הזו תומכת בתגי עיצוב, ולכן היא יכולה לקשר למסמכי תיעוד נוספים או להדגיש מילים שחשובות למפתח.
- type מגדיר את מנגנון הקלט של האופן שבו משתמש מגדיר את ערך הפרמטר. יש הרבה סוגים, כולל
string
,select
,multiSelect
,selectResource
ו-secret
. למידע נוסף על כל אחת מהאפשרויות האלה, עיינו במאמרי העזרה. - validationRegex מגביל את הערך שהמפתח מזין לערך ביטוי רגולרי מסוים (בדוגמה, הוא מבוסס על ההנחיות לבחירת שמות שדות פשוטים שזמינות כאן). אם הבדיקה נכשלת…
- validationErrorMessage מתריע למפתח על ערך הכשל.
- default הוא הערך שיהיה אם המפתח לא מזין טקסט.
- המשמעות של חובה היא שהמפתח לא נדרש להזין טקסט.
- הערך לא ניתן לשינוי מאפשר למפתח לעדכן את התוסף הזה ולשנות את הערך. במקרה כזה, למפתח צריכה להיות אפשרות לשנות שמות של שדות כשהדרישות שלהם משתנות.
- דוגמה מספקת מושג לגבי האופן שבו קלט חוקי עשוי להיראות.
זה היה הרבה מידע להבין!
- יש עוד שלושה פרמטרים שצריך להוסיף לקובץ
extension.yaml
לפני שמוסיפים פרמטר מיוחד.
- 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
הגדרת פרמטרים רגישים
עכשיו צריך לנהל את מפתח ה-API שהמשתמש מציין. זוהי מחרוזת רגישה שאין לשמור אותה בטקסט פשוט בפונקציה. במקום זאת, כדאי לאחסן את הערך הזה ב-Cloud secret manager. זהו מיקום מיוחד בענן שבו מאוחסנים סודות מוצפנים, כדי למנוע דליפת מידע בטעות. כדי לעשות זאת, המפתח צריך לשלם על השימוש בשירות הזה, אבל הוא מוסיף שכבת אבטחה נוספת למפתחות ה-API שלו ויכול להגביל פעילות שמקורה בתרמית. במסמכי התיעוד למשתמשים מוצג התראה למפתחים על כך שמדובר בשירות בתשלום, כדי שלא יהיו הפתעות בחיוב. באופן כללי, השימוש דומה למשאבי המחרוזות האחרים שצוינו למעלה. ההבדל היחיד הוא הסוג שנקרא secret
.
- לקובץ
extension.yaml
, מוסיפים את הקוד הבא:
extension.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
עדכון המאפיינים resource
כדי להשתמש בפרמטרים
כפי שצוין קודם, המשאב (ולא הפונקציה) מגדיר את אופן המעקב אחרי המשאב, לכן צריך לעדכן את המשאב locationUpdate
כדי להשתמש בפרמטר החדש.
- לקובץ
extension.yaml
, מוסיפים את הקוד הבא:
extension.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}
בודקים את הקובץ extension.yaml
- בודקים את הקובץ
extension.yaml
. הוא אמור להיראות כך:
extension.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.
גישה לפרמטרים בקוד
עכשיו, אחרי שכל הפרמטרים מוגדרים בקובץ extension.yaml
, מוסיפים אותם לקובץ index.ts
.
- בקובץ
index.ts
, מחליפים את ערכי ברירת המחדל בטקסטprocess.env.PARAMETER_NAME
, שמאחזר את ערכי הפרמטרים המתאימים ומאכלס אותם בקוד הפונקציה שנפרס בפרויקט Firebase של המפתח.
index.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!;
בדרך כלל, כדאי לבצע בדיקות של ערכים null עם ערכי משתני הסביבה, אבל במקרה הזה, אתם יכולים לסמוך על כך שערכי הפרמטרים מועתקים בצורה נכונה. עכשיו הקוד מוגדר לפעול עם הפרמטרים של התוסף.
7. יצירת מסמכי תיעוד למשתמשים
לפני שבודקים את הקוד במהדמנים או בזירת המסחר של התוספים של Firebase, צריך לתעד את התוסף כדי שהמפתחים ידעו מה הם מקבלים כשהם משתמשים בו.
- מתחילים ביצירת הקובץ
PREINSTALL.md
, שמשמשים לתיאור הפונקציונליות, הדרישות המוקדמות להתקנה וההשלכות האפשריות על החיוב.
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)
- כדי לחסוך זמן בכתיבת
README.md
בפרויקט הזה, אפשר להשתמש בשיטה הנוחות:
firebase ext:info . --markdown > README.md
השילוב הזה כולל את התוכן של הקובץ PREINSTALL.md
ופרטים נוספים על התוסף מהקובץ extension.yaml
.
לבסוף, עליכם להודיע למפתח התוסף על פרטים נוספים לגבי התוסף שהותקן. יכול להיות שהמפתח יקבל הוראות ומידע נוספים אחרי השלמת ההתקנה, וייתכן שהוא יקבל משימות מפורטות לאחר ההתקנה, כמו הגדרת קוד לקוח.
- יוצרים קובץ
POSTINSTALL.md
ומוסיפים את הפרטים הבאים אחרי ההתקנה:
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);
});
מעקב
מומלץ לעקוב אחרי הפעילות של התוסף שהותקן, כולל בדיקות של התקינות, השימוש והיומנים שלו.
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
הפעולה הזו יוצרת מחדש את הפונקציות כך שקוד המקור העדכני ביותר מוכן לפריסה לצד התוסף כשהוא נפרס באמולטור או ישירות ב-Firebase.
לאחר מכן יוצרים ספרייה חדשה שממנה רוצים לבדוק את התוסף. מכיוון שהתוסף פותח מפונקציות קיימות, אל תבדקו בתיקייה שבה הוגדר התוסף, כי היא מנסה לפרוס את הפונקציות ואת כללי Firebase לצדה.
התקנה ובדיקה באמצעות אמולטורים של Firebase
- יוצרים ספרייה חדשה במערכת המארחת ומקשרים אותה לפרויקט Firebase באמצעות
firebase init
.
mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- בספרייה הזו, מריצים את
firebase ext:install
כדי להתקין את התוסף. מחליפים את/path/to/extension
בנתיב המוחלט לספרייה שמכילה את הקובץextension.yaml
. הפקודה הזו מפעילה את תהליך ההתקנה של התוסף ויוצרת קובץ.env
שמכיל את ההגדרות שלכם, לפני שההגדרות מועברות אל Firebase או אל המהדמנים.
firebase ext:install /path/to/extension
- מכיוון שפורסים את הפרויקט באופן מקומי, מציינים שרוצים להשתמש בקובץ מקומי במקום ב-Google Cloud Secret Manager.
- מפעילים את חבילת הכלים לאמולטור המקומי:
firebase emulators:start
התקנה ובדיקה באמצעות פרויקט Firebase אמיתי
אפשר להתקין את התוסף בפרויקט Firebase בפועל. מומלץ להשתמש בפרויקט בדיקה כדי לבדוק את הניסוי. מומלץ להשתמש בתהליך העבודה הזה לבדיקה אם אתם רוצים לבדוק את התהליך מקצה לקצה של התוסף, או אם הטריגר של התוסף עדיין לא נתמך בחבילת הסימולטורים של Firebase (ראו האפשרות 'סימולטור של תוספים'). האמולטורים תומכים כרגע בפונקציות שמופעלות על ידי בקשת HTTP ובפונקציות שמופעלות ברקע על ידי אירוע ברקע עבור Cloud Firestore, מסד נתונים בזמן אמת ו-Pub/Sub.
- יוצרים ספרייה חדשה במערכת המארחת ומחברים אותה לפרויקט Firebase באמצעות
firebase init
.
cd .. mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- לאחר מכן, מריצים את
firebase ext:install
מהספרייה הזו כדי להתקין את התוסף. מחליפים את/path/to/extension
בנתיב המוחלט לספרייה שמכילה את הקובץextension.yaml
. הפעולה הזו תתחיל את תהליך ההתקנה של התוסף ותיצור קובץ.env
שמכיל את ההגדרות האישיות שלכם, לפני שמעבירים את התצורה ל-Firebase או לאמולטורים.
firebase ext:install /path/to/extension
- מכיוון שאתם רוצים לפרוס את האפליקציה ישירות ב-Firebase ולהשתמש ב-Google Cloud Secret Manager, עליכם להפעיל את Secret Manager API לפני שמתקינים את התוסף.
- פורסים את האפליקציה בפרויקט Firebase.
firebase deploy
בדיקת התוסף
- אחרי שמריצים את הקוד
firebase deploy
אוfirebase emulators:start
, עוברים לכרטיסייה Firestore במסוף Firebase או ב-WebView של האמולטורים, לפי הצורך. - הוספת מסמך לאוסף שצוין בשדה
x
ובשדהy
. במקרה כזה, המסמכים המעודכנים נמצאים ב-u/{uid}
עם שדהx
שלxv
ושדהy
שלyv
.
- אם ההתקנה של התוסף הושלמה, אחרי שמשמרים את שני השדות, התוסף יוצר שדה חדש בשם
hash
במסמך.
8. כל הכבוד!
המרת בהצלחה את הפונקציה הראשונה של Cloud Functions לתוסף של Firebase!
הוספתם קובץ extension.yaml
והגדרתם אותו כך שמפתחים יוכלו לבחור איך לפרוס את התוסף. לאחר מכן יצרתם מסמכי עזרה למשתמש עם הנחיות למפתחים של התוסף לגבי הפעולות שהם צריכים לבצע לפני הגדרת התוסף, וגם לגבי השלבים שהם עשויים להידרש לבצע אחרי התקנת התוסף.
עכשיו אתם יודעים מהם השלבים העיקריים שנדרשים כדי להמיר פונקציית Firebase לתוסף Firebase שניתן להפצה.