1. לפני שמתחילים
תוסף ל-Firebase מבצע משימה ספציפית או קבוצה של משימות בתגובה לבקשות HTTP או לאירועים שמופעלים ממוצרים אחרים של Firebase ו-Google, כמו העברת הודעות בענן ב-Firebase, Cloud Firestore או Pub/Sub.
מה תפַתחו
בקודלאב הזה תלמדו איך ליצור תוסף ל-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. בקודלאב הזה נעשה שימוש ב-Cloud Functions, כך שאם אתם משתמשים בפרויקט Firebase אמיתי במקום במהכלי האימולציה, תצטרכו לשדרג לחבילת התמחור Blaze.
רוצים לדלג קדימה?
אפשר להוריד גרסה מושלמת של הקוד. אם נתקעתם בדרך או אם אתם רוצים לראות איך נראה תוסף שהושלם, תוכלו לבדוק את ההסתעפות codelab-end
במאגר GitHub או להוריד את קובץ ה-zip המלא.
3. בדיקת הקוד
- פותחים את הקובץ
index.ts
מקובץ ה-zip. שימו לב שהיא מכילה שתי הצהרות של Cloud Functions.
מה הפונקציות האלה עושות?
פונקציות הדגמה האלה משמשות ליצירת גיאוהאש. הם מקבלים זוג קואורדינטות וממירים אותו לפורמט שמותאם לשאילתות גיאוגרפיות ב-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. כשאירוע כתיבת נתונים מתרחש במסד הנתונים, הפונקציה מגיבה לאירוע הזה על ידי חיפוש של שדה xv
ושדה yv
. אם שני השדות האלה קיימים, היא מחשבת את ה-geohash וכותבת את הפלט למיקום פלט מוגדר של מסמך. מסמך הקלט מוגדר על ידי הקבוע users/{uid}
, כלומר הפונקציה קוראת כל מסמך שנכתב באוסף users/
ולאחר מכן מעבדת גיאוהאש למסמכים האלה. לאחר מכן, הוא מוציא את הגיבוב לשדה גיבוב באותו מסמך.
פונקציות שניתן להפעיל
הפונקציה הבאה בקובץ 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
, יוצרים משאב חדש בנכס resources. המאפיינים האלה ספציפיים לפונקציה שניתן לבצע קריאה אליה:
- 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 בתצוגת האינטרנט של המהדמנים. - מוסיפים מסמך לאוסף
users
עם שדה מספרxv
ושדה מספרyv
.
- אם ההתקנה של התוסף הושלמה, התוסף יוצר במסמך שדה חדש בשם
hash
.
ניקוי כדי למנוע התנגשויות
- אחרי שנסיים את הבדיקה, נצטרך להסיר את התוסף. אנחנו עומדים לעדכן את קוד התוסף, ולא רוצים שיהיה לו קונפליקט עם התוסף הנוכחי בשלב מאוחר יותר.
אפשר להתקין כמה גרסאות של אותו תוסף בו-זמנית, ולכן הסרת התוסף מבטיחה שלא יהיו התנגשויות עם תוסף שהותקן בעבר.
firebase ext:uninstall geohash-ext
הפתרון הנוכחי פועל, אבל כפי שצוין בתחילת הפרויקט, יש מפתח API מקודד מראש כדי לדמות תקשורת עם שירות. איך משתמשים במפתח ה-API של משתמש הקצה במקום במפתח המקורי שסופק? כדאי לקרוא בהמשך כדי לגלות.
6. איך מאפשרים למשתמשים להגדיר את התוסף
בשלב הזה בקודלאב, יש לכם תוסף שמוגדר לשימוש עם ההגדרה המוגדרת מראש של הפונקציות שכבר כתבתם, אבל מה קורה אם המשתמש רוצה להשתמש בקו הרוחב ובקו האורך במקום ב-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 – תיאור מפורט של הערך. מכיוון שהתג הזה תומך ב-Markdown, אפשר לקשר אותו למסמכי עזרה נוספים או להדגיש מילים שעשויות להיות חשובות למפתח.
- type מגדיר את מנגנון הקלט של האופן שבו משתמש מגדיר את ערך הפרמטר. יש הרבה סוגים, כולל
string
,select
,multiSelect
,selectResource
ו-secret
. מידע נוסף על כל אחת מהאפשרויות האלה זמין במסמכי התיעוד. - validationRegex מגביל את הערך שהמפתח מזין לערך ביטוי רגולרי מסוים (בדוגמה, הוא מבוסס על ההנחיות לבחירת שמות שדות פשוטים שזמינות כאן). אם הפעולה הזו נכשלת…
- validationErrorMessage מתריע למפתח על ערך הכשל.
- default הוא הערך שיהיה אם המפתח לא מזין טקסט.
- הערך required מציין שהמפתח לא חייב להזין טקסט.
- הערך immutable מאפשר למפתח לעדכן את התוסף הזה ולשנות את הערך הזה. במקרה כזה, המפתח אמור להיות מסוגל לשנות את שמות השדות בהתאם לשינויים בדרישות.
- example מאפשרת לכם לראות איך נראה קלט תקין.
זה היה הרבה מידע להבין!
- יש לכם עוד שלושה פרמטרים להוסיף לקובץ
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, ב-Realtime Database וב-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 או בתצוגת האינטרנט של המהדמנים, לפי הצורך. - הוספת מסמך לאוסף שצוין בשדה
x
ובשדהy
. במקרה כזה, המסמכים המעודכנים נמצאים ב-u/{uid}
עם שדהx
שלxv
ושדהy
שלyv
.
- אם התוסף הוטמע בהצלחה, הוא יוצר שדה חדש בשם
hash
במסמך אחרי שמשמרים את שני השדות.
8. כל הכבוד!
הפונקציה הראשונה של Cloud Functions הומרתה בהצלחה לתוסף ל-Firebase!
הוספתם קובץ extension.yaml
והגדרתם אותו כך שמפתחים יוכלו לבחור איך לפרוס את התוסף. לאחר מכן יצרתם מסמכי עזרה למשתמש עם הנחיות למפתחים של התוסף לגבי הפעולות שהם צריכים לבצע לפני הגדרת התוסף, וגם לגבי השלבים שהם עשויים להידרש לבצע אחרי התקנת התוסף.
עכשיו אתם יודעים מהם השלבים העיקריים שצריך לבצע כדי להמיר פונקציית Firebase לתוסף Firebase שניתן להפצה.