התחל בבניית הרחבה

דף זה מנחה אותך בשלבים הנדרשים לבניית תוסף Firebase פשוט, שתוכל להתקין בפרויקטים שלך או לשתף עם אחרים. דוגמה פשוטה זו של תוסף Firebase תצפה במסד הנתונים בזמן אמת שלך עבור הודעות ותמיר אותן לאותיות רישיות.

1. הגדר את הסביבה שלך ואתחול פרויקט

לפני שתוכל להתחיל לבנות הרחבה, תצטרך להגדיר סביבת בנייה עם הכלים הנדרשים.

  1. התקן את Node.js 16 ומעלה. דרך אחת להתקין את Node היא באמצעות nvm (או nvm-windows ).

  2. התקן או עדכן לגרסה העדכנית ביותר של Firebase CLI . כדי להתקין או לעדכן באמצעות npm , הפעל את הפקודה הזו:

    npm install -g firebase-tools
    

כעת השתמש ב-Firebase CLI כדי לאתחל פרויקט הרחבה חדש:

  1. צור ספרייה עבור התוסף שלך cd לתוכו:

    mkdir rtdb-uppercase-messages && cd rtdb-uppercase-messages
    
  2. הפעל את הפקודה ext:dev:init של Firebase CLI:

    firebase ext:dev:init
    

    כאשר תתבקש, בחר JavaScript כשפה לפונקציות (אך שים לב שאתה יכול להשתמש גם ב-TypeScript כאשר אתה מפתח תוסף משלך), וכאשר תתבקש להתקין תלות, ענה "כן". (קבל את ברירת המחדל עבור כל אפשרויות אחרות.) פקודה זו תגדיר בסיס קוד שלד עבור הרחבה חדשה, שממנו תוכל להתחיל לפתח את ההרחבה שלך.

2. נסה את התוסף לדוגמה באמצעות האמולטור

כאשר Firebase CLI אתחל את ספריית ההרחבות החדשה, הוא יצר פונקציה פשוטה לדוגמה וספריית integration-tests המכילה את הקבצים הדרושים להפעלת הרחבה באמצעות חבילת האמולטורים של Firebase.

נסה להריץ את התוסף לדוגמה באמולטור:

  1. שנה לספריית integration-tests :

    cd functions/integration-tests
    
  2. התחל את האמולטור עם פרויקט הדגמה:

    firebase emulators:start --project=demo-test
    

    האמולטור טוען את התוסף לפרויקט "דמה" מוגדר מראש ( demo-test ). התוסף עד כה מורכב מפונקציה אחת מופעלת ב-HTTP, greetTheWorld , אשר מחזירה הודעת "שלום עולם" בעת גישה.

  3. כשהאמולטור עדיין פועל, נסה את הפונקציה greetTheWorld של התוסף על ידי ביקור בכתובת ה-URL שהודפסה כשהתחלת אותה.

    הדפדפן שלך מציג את ההודעה "Hello World from Greet-the-world".

  4. קוד המקור של פונקציה זו נמצא בספריית functions של התוסף. פתח את המקור בעורך או ב-IDE לפי בחירתך:

    functions/index.js

    const functions = require("firebase-functions");
    
    exports.greetTheWorld = functions.https.onRequest((req, res) => {
      // Here we reference a user-provided parameter
      // (its value is provided by the user during installation)
      const consumerProvidedGreeting = process.env.GREETING;
    
      // And here we reference an auto-populated parameter
      // (its value is provided by Firebase after installation)
      const instanceId = process.env.EXT_INSTANCE_ID;
    
      const greeting = `${consumerProvidedGreeting} World from ${instanceId}`;
    
      res.send(greeting);
    });
    
  5. בזמן שהאמולטור פועל, הוא יטען מחדש אוטומטית כל שינוי שתבצע בקוד הפונקציות שלך. נסה לעשות שינוי קטן בפונקציה greetTheWorld :

    functions/index.js

    const greeting = `${consumerProvidedGreeting} everyone, from ${instanceId}`;
    

    שמור את השינויים שלך. האמולטור יטען מחדש את הקוד שלך, וכעת, כאשר אתה מבקר בכתובת ה-URL של הפונקציה, תראה את הברכה המעודכנת.

3. הוסף מידע בסיסי ל-extension.yaml

כעת, לאחר שהגדרת סביבת פיתוח ואתה מפעיל את אמולטור ההרחבות, אתה יכול להתחיל לכתוב הרחבה משלך.

כצעד ראשון צנוע, ערוך את המטא-נתונים של התוסף המוגדרים מראש כך שישקפו את התוסף שברצונך לכתוב במקום greet-the-world . מטא נתונים אלה מאוחסנים בקובץ extension.yaml .

  1. פתח את extension.yaml בעורך שלך, והחלף את כל תוכן הקובץ בדברים הבאים:

    name: rtdb-uppercase-messages
    version: 0.0.1
    specVersion: v1beta  # Firebase Extensions specification version; don't change
    
    # Friendly display name for your extension (~3-5 words)
    displayName: Convert messages to upper case
    
    # Brief description of the task your extension performs (~1 sentence)
    description: >-
      Converts messages in RTDB to upper case
    
    author:
      authorName: Your Name
      url: https://your-site.example.com
    
    license: Apache-2.0  # Required license
    
    # Public URL for the source code of your extension
    sourceUrl: https://github.com/your-name/your-repo
    

    שימו לב למוסכמות השמות המשמשות בשדה name : הרחבות הרשמיות של Firebase נקראות עם קידומת המציינת את המוצר הראשי של Firebase שעליו פועל התוסף, ולאחר מכן תיאור של מה התוסף עושה. עליך להשתמש באותה מוסכמה בהרחבות משלך.

  2. מכיוון ששינית את שם התוסף שלך, עליך לעדכן גם את תצורת האמולטור שלך בשם החדש:

    1. ב- functions/integration-tests/firebase.json , שנה greet-the-world ל- rtdb-uppercase-messages .
    2. שנה את שם functions/integration-tests/extensions/greet-the-world.env ל- functions/integration-tests/extensions/rtdb-uppercase-messages.env .

עדיין נותרו כמה שרידים של תוסף greet-the-world בקוד התוסף שלך, אבל השאר אותם לעת עתה. אתה תעדכן אותם בחלקים הבאים.

4. כתוב פונקציית ענן והכריז עליה כמשאב הרחבה

עכשיו אתה יכול להתחיל לכתוב קצת קוד. בשלב זה, תכתוב פונקציית ענן שמבצעת את משימת הליבה של התוסף שלך, שהיא לצפות במסד הנתונים בזמן אמת שלך עבור הודעות ולהמיר אותן לאותיות גדולות.

  1. פתח את המקור לפונקציות של התוסף (בספריית functions של התוסף) בעורך או ב-IDE לפי בחירתך. החלף את תוכנו בדברים הבאים:

    functions/index.js

    import { database, logger } from "firebase-functions/v1";
    
    const app = initializeApp();
    
    // Listens for new messages added to /messages/{pushId}/original and creates an
    // uppercase version of the message to /messages/{pushId}/uppercase
    // for all databases in 'us-central1'
    export const makeuppercase = database
      .ref("/messages/{pushId}/uppercase")
      .onCreate(async (snapshot, context) => {
        // Grab the current value of what was written to the Realtime Database.
        const original = snapshot.val();
    
        // Convert it to upper case.
        logger.log("Uppercasing", context.params.pushId, original);
        const uppercase = original.toUpperCase();
    
        // Setting an "uppercase" sibling in the Realtime Database.
        const upperRef = snapshot.ref.parent.child("upper");
        await upperRef.set(uppercase);
    });
    

    הפונקציה הישנה, ​​שהחלפת, הייתה פונקציה שהופעלה על ידי HTTP, אשר רצה כאשר ניגשו לנקודת קצה HTTP. הפונקציה החדשה מופעלת על ידי אירועי מסד נתונים בזמן אמת: היא מחפשת פריטים חדשים בנתיב מסוים, וכאשר מתגלה, היא כותבת את הגרסה האותיות של הערך בחזרה למסד הנתונים.

    אגב, הקובץ החדש הזה משתמש בתחביר מודול ECMAScript ( import export ) במקום CommonJS ( require ). כדי להשתמש במודולי ES ב-Node, ציין "type": "module" ב- functions/package.json :

    {
      "name": "rtdb-uppercase-messages",
      "main": "index.js",
      "type": "module",
      …
    }
    
  2. כל פונקציה בסיומת שלך חייבת להיות מוצהרת בקובץ extension.yaml . ההרחבה לדוגמה הכריזה על greetTheWorld כפונקציית הענן היחידה של התוסף; כעת, לאחר שהחלפת אותו makeuppercase , עליך גם לעדכן את ההצהרה שלו.

    פתח extension.yaml והוסף שדה resources :

    resources:
      - name: makeuppercase
        type: firebaseextensions.v1beta.function
        properties:
          eventTrigger:
            eventType: providers/google.firebase.database/eventTypes/ref.create
            # DATABASE_INSTANCE (project's default instance) is an auto-populated
            # parameter value. You can also specify an instance.
            resource: projects/_/instances/${DATABASE_INSTANCE}/refs/messages/{pushId}/original
          runtime: "nodejs18"
    
  3. מכיוון שהתוסף שלך משתמש כעת במסד נתונים בזמן אמת כטריגר, עליך לעדכן את תצורת האמולטור שלך כדי להפעיל את אמולטור RTDB לצד אמולטור Cloud Functions:

    1. אם האמולטור עדיין פועל, עצור אותו על ידי לחיצה על Ctrl-C.

    2. מתוך ספריית functions/integration-tests , הפעל את הפקודה הבאה:

      firebase init emulators
      

      כאשר תתבקש, דלג על הגדרת פרויקט ברירת מחדל, ולאחר מכן בחר באמולטורים של פונקציות ומסד נתונים. קבל את יציאות ברירת המחדל ואפשר לכלי ההגדרה להוריד את כל הקבצים הנדרשים.

    3. הפעל מחדש את האמולטור:

      firebase emulators:start --project=demo-test
      
  4. נסה את התוסף המעודכן שלך:

    1. פתח את ממשק המשתמש של אמולטור מסד הנתונים באמצעות הקישור שהאמולטור הדפיס כשהתחלת אותו.

    2. ערוך את צומת הבסיס של מסד הנתונים:

      • שדה: messages
      • סוג: json
      • ערך: {"11": {"original": "recipe"}}

      אם הכל מוגדר כהלכה, כאשר אתה שומר את השינויים במסד הנתונים שלך, פונקציית makeuppercase של התוסף אמורה להפעיל ולהוסיף רשומת צאצא להודעה 11 עם התוכן "upper": "RECIPE" . עיין ביומנים ובכרטיסיות מסד הנתונים של ממשק המשתמש של האמולטור כדי לאשר את התוצאות הצפויות.

    3. נסה להוסיף עוד כמה ילדים לצומת messages ( {"original":"any text"} ). בכל פעם שאתה מוסיף רשומה חדשה, התוסף צריך להוסיף שדה uppercase המכיל את התוכן האותיות של השדה original .

כעת יש לך הרחבה מלאה, אם כי פשוטה, הפועלת על מופע RTDB. בסעיפים הבאים, תחדד את התוסף הזה עם כמה תכונות נוספות. לאחר מכן, תכין את התוסף להפצה לאחרים, ולבסוף, תלמד כיצד לפרסם את התוסף שלך ב- Extensions Hub.

5. הצהר על ממשקי API ותפקידים

Firebase מעניקה לכל מופע של תוסף מותקן גישה מוגבלת לפרויקט ולנתונים שלו באמצעות חשבון שירות לכל מופע. לכל חשבון יש את קבוצת ההרשאות המינימלית הדרושה לפעולה. מסיבה זו, עליך להצהיר במפורש על כל תפקידי IAM שההרחבה שלך דורשת; כאשר משתמשים מתקינים את התוסף שלך, Firebase יוצר חשבון שירות עם התפקידים הללו ומשתמש בו כדי להפעיל את התוסף.

אתה לא צריך להכריז על תפקידים כדי להפעיל אירועים של מוצר, אבל אתה צריך להכריז על תפקיד כדי ליצור איתו אינטראקציה אחרת. מכיוון שהפונקציה שהוספת בשלב האחרון כותבת ל-Realtime Database, עליך להוסיף את ההצהרה הבאה ל- extension.yaml :

roles:
  - role: firebasedatabase.admin
    reason: Allows the extension to write to RTDB.

באופן דומה, אתה מצהיר על ממשקי ה-API של Google שבהם תוסף משתמש בשדה ה- apis . כאשר משתמשים מתקינים את התוסף שלך, הם יישאלו אם הם רוצים להפעיל אוטומטית ממשקי API אלה עבור הפרויקט שלהם. זה בדרך כלל נחוץ רק עבור ממשקי API שאינם Firebase Google, ואינו נחוץ עבור מדריך זה.

6. הגדר פרמטרים הניתנים להגדרה על ידי המשתמש

הפונקציה שיצרת בשני השלבים האחרונים צפתה במיקום RTDB ספציפי להודעות נכנסות. לפעמים, צפייה במיקום ספציפי היא באמת מה שאתה רוצה, למשל כאשר התוסף שלך פועל על מבנה מסד נתונים שבו אתה משתמש באופן בלעדי עבור ההרחבה שלך. עם זאת, לרוב, תרצה להפוך את הערכים הללו לניתנים להגדרה על ידי משתמשים שמתקינים את התוסף שלך בפרויקטים שלהם. בדרך זו, משתמשים יכולים לעשות שימוש בתוסף שלך כדי לעבוד עם הגדרת מסד הנתונים הקיימת שלהם.

הפוך את הנתיב שבו התוסף צופה להודעות חדשות לניתן להגדרה על ידי המשתמש:

  1. בקובץ extension.yaml , הוסף קטע params :

    - param: MESSAGE_PATH
      label: Message path
      description: >-
        What is the path at which the original text of a message can be found?
      type: string
      default: /messages/{pushId}/original
      required: true
      immutable: false
    

    זה מגדיר פרמטר מחרוזת חדש שמשתמשים יתבקשו להגדיר כשהם מתקינים את התוסף שלך.

  2. עדיין בקובץ extension.yaml , חזור להצהרת makeuppercase שלך ושנה את שדה resource לשדה הבא:

    resource: projects/_/instances/${DATABASE_INSTANCE}/refs/${param:MESSAGE_PATH}
    

    האסימון ${param:MESSAGE_PATH} הוא הפניה לפרמטר שזה עתה הגדרת. כאשר ההרחבה שלך פועלת, האסימון הזה יוחלף בכל ערך שהמשתמש הגדיר עבור פרמטר זה, וכתוצאה מכך פונקציית makeuppercase תקשיב לנתיב שהמשתמש ציין. אתה יכול להשתמש בתחביר זה כדי להתייחס לכל פרמטר מוגדר על ידי משתמש בכל מקום ב- extension.yaml (וב- POSTINSTALL.md - עוד על כך בהמשך).

  3. אתה יכול גם לגשת לפרמטרים המוגדרים על ידי המשתמש מקוד הפונקציות שלך.

    בפונקציה שכתבת בסעיף האחרון, קודדת קשה את הנתיב כדי לצפות בשינויים. שנה את הגדרת הטריגר כדי להתייחס לערך המוגדר על ידי המשתמש במקום זאת:

    functions/index.js

    export const makeuppercase = database.ref(process.env.MESSAGE_PATH).onCreate
    

    שימו לב שב-Firebase Extensions, השינוי הזה נועד אך ורק למען התיעוד: כאשר פונקציית Cloud נפרסת כחלק מהרחבה, היא משתמשת בהגדרת הטריגר מהקובץ extension.yaml ומתעלמת מהערך שצוין בהגדרת הפונקציה. עם זאת, מומלץ לתעד בקוד שלך מהיכן מגיע הערך הזה.

  4. אולי תמצא את זה מאכזב לבצע שינוי קוד שאין לו אפקט זמן ריצה, אבל הלקח החשוב שיש לקחת הוא שאתה יכול לגשת לכל פרמטר מוגדר על ידי משתמש בקוד הפונקציה שלך ולהשתמש בו כערך רגיל בלוגיקה של הפונקציה. כהנהון ליכולת זו, הוסף את הצהרת היומן הבאה כדי להדגים שאתה אכן ניגש לערך שהמשתמש הגדיר:

    functions/index.js

    export const makeuppercase = database.ref(process.env.MESSAGE_PATH).onCreate(
      async (snapshot, context) => {
        logger.log("Found new message at ", snapshot.ref);
    
        // Grab the current value of what was written to the Realtime Database.
        ...
    
  5. בדרך כלל, משתמשים מתבקשים לספק ערכים עבור פרמטרים כאשר הם מתקינים תוסף. עם זאת, כאשר אתה משתמש באמולטור לבדיקה ופיתוח, אתה מדלג על תהליך ההתקנה, כך שאתה מספק במקום זאת ערכים לפרמטרים המוגדרים על ידי המשתמש באמצעות קובץ env .

    פתח functions/integration-tests/extensions/rtdb-uppercase-messages.env והחלף את הגדרת GREETING בהגדרה הבאה:

    MESSAGE_PATH=/msgs/{pushId}/original
    

    שימו לב שהנתיב שלמעלה שונה מנתיב ברירת המחדל ומהנתיב שהגדרת קודם לכן; זה רק כדי להוכיח לעצמך כשאתה מנסה את התוסף המעודכן שלך שההגדרה שלך נכנסת לתוקף.

  6. כעת, הפעל מחדש את האמולטור ובקר שוב בממשק המשתמש של אמולטור מסד הנתונים.

    ערוך את צומת הבסיס של מסד הנתונים, באמצעות הנתיב שהגדרת למעלה:

    • שדה: msgs
    • סוג: json
    • ערך: {"11": {"original": "recipe"}}

    כאשר אתה שומר את השינויים במסד הנתונים שלך, פונקציית makeuppercase של התוסף אמורה להפעיל כמו בעבר, אך כעת היא אמורה גם להדפיס את הפרמטר המוגדר על ידי המשתמש ליומן המסוף.

7. ספק ווים לאירועים עבור לוגיקה מוגדרת על ידי המשתמש

כבר ראית, כמחבר הרחבה, כיצד מוצר Firebase יכול להפעיל את ההיגיון שסופק על ידי התוסף שלך: יצירת רשומות חדשות במסד נתונים בזמן אמת מפעילה את פונקציית makeuppercase שלך. לתוסף שלך יכול להיות קשר מקביל עם המשתמשים שמתקינים את התוסף שלך: התוסף שלך יכול להפעיל לוגיקה שהמשתמש מגדיר.

הרחבה יכולה לספק ווים סינכרוניים , ווים אסינכרוניים , או שניהם. ווים סינכרוניים נותנים למשתמשים דרך לבצע משימות החוסמות את השלמת אחת מהפונקציות של התוסף. זה יכול להיות שימושי, למשל, כדי לתת למשתמשים דרך לבצע עיבוד מקדים מותאם אישית לפני שתוסף יעשה את עבודתו.

במדריך זה, תוסיף הוק אסינכרוני לתוסף שלך, שיאפשר למשתמשים להגדיר שלבי עיבוד משלהם שיופעלו לאחר שההרחבה שלך כותבת את ההודעה האותיות הגדולות למסד הנתונים בזמן אמת. ווים אסינכרוניים משתמשים ב- Eventarc כדי להפעיל פונקציות מוגדרות על ידי המשתמש. תוספים מצהירים על סוגי האירועים שהם פולטים, וכאשר משתמשים מתקינים את התוסף, הם בוחרים באילו סוגי אירועים הם מעוניינים. אם הם בוחרים לפחות אירוע אחד, Firebase תספק ערוץ Eventarc עבור התוסף כחלק מתהליך ההתקנה . לאחר מכן, המשתמשים יכולים לפרוס פונקציות ענן משלהם שמאזינות בערוץ זה ומופעלות כאשר התוסף מפרסם אירועים חדשים.

בצע את השלבים הבאים כדי להוסיף וו אסינכרוני:

  1. בקובץ extension.yaml , הוסף את הסעיף הבא, שמצהיר על סוג האירוע האחד שהסיומת פולטת:

    events:
      - type: test-publisher.rtdb-uppercase-messages.v1.complete
        description: >-
          Occurs when message uppercasing completes. The event subject will contain
          the RTDB URL of the uppercase message.
    

    סוגי אירועים חייבים להיות ייחודיים אוניברסליים; כדי להבטיח ייחודיות, תמיד תן שם לאירועים שלך בפורמט הבא: <publisher-id>.<extension-id>.<version>.<description> . (אין לך עדיין מזהה בעל אתר, אז פשוט השתמש test-publisher לעת עתה.)

  2. בסוף פונקציית makeuppercase , הוסף קוד כלשהו שמפרסם אירוע מהסוג שהצהרת זה עתה:

    functions/index.js

    // Import the Eventarc library:
    import { initializeApp } from "firebase-admin/app";
    import { getEventarc } from "firebase-admin/eventarc";
    
    const app = initializeApp();
    
    // In makeuppercase, after upperRef.set(uppercase), add:
    
    // Set eventChannel to a newly-initialized channel, or `undefined` if events
    // aren't enabled.
    const eventChannel =
      process.env.EVENTARC_CHANNEL &&
      getEventarc().channel(process.env.EVENTARC_CHANNEL, {
        allowedEventTypes: process.env.EXT_SELECTED_EVENTS,
      });
    
    // If events are enabled, publish a `complete` event to the configured
    // channel.
    eventChannel &&
      eventChannel.publish({
        type: "test-publisher.rtdb-uppercase-messages.v1.complete",
        subject: upperRef.toString(),
        data: {
          "original": original,
          "uppercase": uppercase,
        },
      });
    

    קוד דוגמה זה מנצל את העובדה שמשתנה הסביבה EVENTARC_CHANNEL מוגדר רק כאשר המשתמש הפעיל לפחות סוג אירוע אחד. אם EVENTARC_CHANNEL אינו מוגדר, הקוד אינו מנסה לפרסם אירועים כלשהם.

    ניתן לצרף מידע נוסף לאירוע Eventarc. בדוגמה שלמעלה, לאירוע יש שדה subject המכיל הפניה לערך החדש שנוצר, ומטען data המכיל את ההודעות המקוריות והאותיות הגדולות. פונקציות מוגדרות על ידי משתמש המפעילות את האירוע יכולות לעשות שימוש במידע זה.

  3. בדרך כלל, משתני הסביבה EVENTARC_CHANNEL ו- EXT_SELECTED_EVENTS מוגדרים על סמך האפשרויות שהמשתמש בחר במהלך ההתקנה. לבדיקה עם האמולטור, הגדר ידנית את המשתנים האלה בקובץ rtdb-uppercase-messages.env :

    EVENTARC_CHANNEL=locations/us-central1/channels/firebase
    EXT_SELECTED_EVENTS=test-publisher.rtdb-uppercase-messages.v1.complete
    

בשלב זה, השלמת את השלבים הדרושים להוספת הוק לאירוע אסינכרוני להרחבה שלך.

כדי לנסות תכונה חדשה זו שיישמת זה עתה, בשלבים הבאים, קבל את התפקיד של משתמש שמתקין את התוסף:

  1. מתוך ספריית functions/integration-tests , אתחל פרויקט Firebase חדש:

    firebase init functions
    

    כאשר תתבקש, דחה להגדיר פרויקט ברירת מחדל, בחר JavaScript כשפת פונקציות הענן והתקן את התלות הנדרשת. פרויקט זה מייצג פרויקט של משתמש , שבו התוסף שלך מותקן.

  2. ערוך integration-tests/functions/index.js והדבק את הקוד הבא:

    import { logger } from "firebase-functions/v1";
    import { onCustomEventPublished } from "firebase-functions/v2/eventarc";
    
    import { initializeApp } from "firebase-admin/app";
    import { getDatabase } from "firebase-admin/database";
    
    const app = initializeApp();
    
    export const extraemphasis = onCustomEventPublished(
      "test-publisher.rtdb-uppercase-messages.v1.complete",
      async (event) => {
        logger.info("Received makeuppercase completed event", event);
    
        const refUrl = event.subject;
        const ref = getDatabase().refFromURL(refUrl);
        const upper = (await ref.get()).val();
        return ref.set(`${upper}!!!`);
      }
    );
    

    זוהי דוגמה לפונקציה שלאחר עיבוד שמשתמש עשוי לכתוב. במקרה זה, הפונקציה מאזינה לסיומת כדי לפרסם אירוע complete , וכאשר היא מופעלת, מוסיפה שלוש סימני קריאה להודעה החדשה עם אותיות רישיות.

  3. הפעל מחדש את האמולטור. האמולטור יטען את הפונקציות של התוסף וכן את פונקציית העיבוד הפוסט שה"משתמש" הגדיר.

  4. בקר בממשק המשתמש של אמולטור מסד הנתונים וערוך את צומת הבסיס של מסד הנתונים, באמצעות הנתיב שהגדרת למעלה:

    • שדה: msgs
    • סוג: json
    • ערך: {"11": {"original": "recipe"}}

    כאשר אתה שומר את השינויים במסד הנתונים שלך, פונקציית makeuppercase של התוסף ופונקציית extraemphasis של המשתמש אמורות להפעיל ברצף, וכתוצאה מכך השדה upper מקבל את הערך RECIPE!!! .

8. הוסף מטפלי אירועים במחזור החיים

התוסף שכתבת עד כה מעבד הודעות תוך כדי יצירתן. אבל מה אם למשתמשים שלך כבר יש מסד נתונים של הודעות כשהם מתקינים את התוסף? ל-Firebase Extensions יש תכונה הנקראת הוקס לאירועי מחזור חיים שבהם אתה יכול להשתמש כדי להפעיל פעולות כאשר התוסף שלך מותקן, מעודכן או מוגדר מחדש. בסעיף זה, תשתמש ב-hooks של אירועי מחזור חיים כדי למלא מחדש את מסד הנתונים של ההודעות הקיים של הפרויקט בהודעות רישיות כאשר משתמש מתקין את התוסף שלך.

Firebase Extensions משתמש ב-Cloud Tasks כדי להפעיל את המטפלים באירועי מחזור החיים שלך. אתה מגדיר מטפלי אירועים באמצעות Cloud Functions; בכל פעם שמופע של ההרחבה שלך מגיע לאחד מאירועי מחזור החיים הנתמכים, אם הגדרת מטפל, הוא יוסיף את המטפל לתור של Cloud Tasks. לאחר מכן, Cloud Tasks יבצעו את המטפל באופן אסינכרוני. בזמן שמטפל באירועי מחזור חיים פועל, מסוף Firebase ידווח למשתמש שלמופע ההרחבה יש משימת עיבוד בתהליך. זה תלוי בפונקציית המטפל שלך לדווח למשתמש על מצב מתמשך והשלמת משימה בחזרה.

כדי להוסיף מטפל באירועי מחזור חיים שממלא מחדש הודעות קיימות, בצע את הפעולות הבאות:

  1. הגדר פונקציית ענן חדשה המופעלת על ידי אירועי תור משימות:

    functions/index.js

    import { tasks } from "firebase-functions/v1";
    
    import { getDatabase } from "firebase-admin/database";
    import { getExtensions } from "firebase-admin/extensions";
    import { getFunctions } from "firebase-admin/functions";
    
    export const backfilldata = tasks.taskQueue().onDispatch(async () => {
      const batch = await getDatabase()
        .ref(process.env.MESSAGE_PATH)
        .parent.parent.orderByChild("upper")
        .limitToFirst(20)
        .get();
    
      const promises = [];
      for (const key in batch.val()) {
        const msg = batch.child(key);
        if (msg.hasChild("original") && !msg.hasChild("upper")) {
          const upper = msg.child("original").val().toUpperCase();
          promises.push(msg.child("upper").ref.set(upper));
        }
      }
      await Promise.all(promises);
    
      if (promises.length > 0) {
        const queue = getFunctions().taskQueue(
          "backfilldata",
          process.env.EXT_INSTANCE_ID
        );
        return queue.enqueue({});
      } else {
        return getExtensions()
          .runtime()
          .setProcessingState("PROCESSING_COMPLETE", "Backfill complete.");
      }
    });
    

    שימו לב שהפונקציה מעבדת רק כמה רשומות לפני שהיא מוסיפה את עצמה חזרה לתור המשימות. זוהי אסטרטגיה נפוצה להתמודדות עם משימות עיבוד שאינן יכולות להשלים בתוך חלון הזמן הקצוב של פונקציית ענן. מכיוון שאינך יכול לחזות כמה הודעות עשויות להיות למשתמש כבר במסד הנתונים שלו כאשר הוא מתקין את התוסף שלך, אסטרטגיה זו מתאימה.

  2. בקובץ extension.yaml , הכריז על פונקציית המילוי החוזר שלך כמשאב הרחבה בעל המאפיין taskQueueTrigger :

    resources:
      - name: makeuppercase
        ...
      - name: backfilldata
        type: firebaseextensions.v1beta.function
        description: >-
          Backfill existing messages with uppercase versions
        properties:
          runtime: "nodejs18"
          taskQueueTrigger: {}
    

    לאחר מכן הכריז על הפונקציה כמטפלת עבור אירוע מחזור החיים onInstall :

    lifecycleEvents:
      onInstall:
        function: backfilldata
        processingMessage: Uppercasing existing messages
    
  3. למרות שמילוי חוזר של הודעות קיימות נחמד לקבל, התוסף עדיין יכול לתפקד בלעדיו. במצבים כאלה, עליך להפוך את הפעלת המטפלים באירועי מחזור החיים לאופציונלית.

    כדי לעשות זאת, הוסף פרמטר חדש ל- extension.yaml :

    - param: DO_BACKFILL
      label: Backfill existing messages
      description: >-
        Generate uppercase versions of existing messages?
      type: select
      required: true
      options:
        - label: Yes
          value: true
        - label: No
          value: false
    

    לאחר מכן, בתחילת פונקציית המילוי החוזר, בדוק את הערך של הפרמטר DO_BACKFILL וצא מוקדם אם הוא לא מוגדר:

    functions/index.js

    if (!process.env.DO_BACKFILL) {
      return getExtensions()
        .runtime()
        .setProcessingState("PROCESSING_COMPLETE", "Backfill skipped.");
    }
    

עם השינויים לעיל, התוסף ימיר כעת הודעות קיימות לאותיות רישיות כאשר הוא מותקן.

עד לנקודה זו, השתמשת באמולטור ההרחבה כדי לפתח את התוסף שלך ולבדוק שינויים מתמשכים. עם זאת, אמולטור ההרחבה מדלג על תהליך ההתקנה, אז כדי לבדוק את המטפל באירוע onInstall שלך, תצטרך להתקין את התוסף בפרויקט אמיתי. עם זאת, זה לא פחות טוב, שכן עם הוספת תכונת המילוי החוזר האוטומטי הזה, תוסף ההדרכה הושלם כעת בקוד!

9. פרוס לתוך פרויקט Firebase אמיתי

למרות שאמולטור ההרחבות הוא כלי נהדר לאיטרציה מהירה של הרחבה במהלך הפיתוח, בשלב מסוים תרצה לנסות אותו בפרויקט אמיתי.

כדי לעשות זאת, תחילה הגדר פרויקט חדש עם כמה שירותים מופעלים:

  1. במסוף Firebase , הוסף פרויקט חדש.
  2. שדרג את הפרויקט שלך לתוכנית Blaze בתשלום. Cloud Functions for Firebase מחייב לפרויקט שלך חשבון חיוב, כך שאתה צריך גם חשבון חיוב כדי להתקין תוסף.
  3. בפרויקט החדש שלך, הפעל מסד נתונים בזמן אמת .
  4. מכיוון שברצונך לבדוק את יכולת התוסף שלך למלא מחדש נתונים קיימים בהתקנה, ייבא כמה נתונים לדוגמה למופע מסד הנתונים שלך בזמן אמת:
    1. הורד כמה נתוני RTDB זרעים .
    2. בדף מסד נתונים בזמן אמת של מסוף Firebase, לחץ על (עוד) > ייבוא ​​JSON ובחר את הקובץ שהורדת זה עתה.
  5. כדי לאפשר לפונקציית המילוי החוזר להשתמש בשיטת orderByChild , הגדר את מסד הנתונים לאינדקס הודעות על הערך של upper :

    {
      "rules": {
        ".read": false,
        ".write": false,
        "messages": {
          ".indexOn": "upper"
        }
      }
    }
    

כעת התקן את התוסף שלך ממקור מקומי בפרויקט החדש:

  1. צור ספרייה חדשה עבור פרויקט Firebase שלך:

    mkdir ~/extensions-live-test && cd ~/extensions-live-test
    
  2. אתחול פרויקט Firebase בספריית העבודה:

    firebase init database
    

    כאשר תתבקש, בחר את הפרויקט שיצרת זה עתה.

  3. התקן את התוסף בפרויקט Firebase המקומי שלך:

    firebase ext:install /path/to/rtdb-uppercase-messages
    

    כאן תוכל לראות מהי חוויית המשתמש בעת התקנת תוסף באמצעות כלי Firebase CLI. הקפד לבחור "כן" כאשר כלי התצורה שואל אם ברצונך למלא מחדש את מסד הנתונים הקיים שלך.

    לאחר שתבחר אפשרויות תצורה, Firebase CLI ישמור את התצורה שלך בספריית extensions ויתעד את מיקום מקור התוסף בקובץ firebase.json . ביחד, שתי הרשומות הללו נקראות מניפסט ההרחבות . משתמשים יכולים להשתמש במניפסט כדי לשמור את תצורת ההרחבות שלהם ולפרוס אותה בפרויקטים שונים.

  4. פרוס את תצורת התוסף שלך בפרויקט החי שלך:

    firebase deploy --only extensions
    

אם הכל ילך כשורה, ה-CLI של Firebase צריך להעלות את התוסף שלך לפרויקט שלך ולהתקין אותו. לאחר סיום ההתקנה, משימת המילוי החוזר תפעל ובתוך מספר דקות, מסד הנתונים שלך יעודכן בהודעות רישיות. הוסף כמה צמתים חדשים למסד הנתונים של ההודעות וודא שהתוסף עובד גם עבור הודעות חדשות.

10. כתוב תיעוד

לפני שתשתף את התוסף שלך עם משתמשים, ודא שאתה מספק מספיק תיעוד כדי שהם יצליחו.

כאשר אתחולת את פרויקט ההרחבה, Firebase CLI יצר גרסאות סטאב של התיעוד המינימלי הנדרש. עדכן את הקבצים האלה כדי לשקף במדויק את התוסף שבנית.

extension.yaml

כבר עדכנת את הקובץ הזה בזמן שפיתחת את התוסף הזה, כך שאינך צריך לבצע עדכונים נוספים כעת.

עם זאת, אל תתעלם מהחשיבות של התיעוד הכלול בקובץ זה. בנוסף למידע המזהה החיוני של הרחבה - שם, תיאור, מחבר, מיקום מאגר רשמי - הקובץ extension.yaml מכיל תיעוד הפונה למשתמש עבור כל משאב ופרמטר הניתן להגדרה על ידי המשתמש. מידע זה מוצג למשתמשים במסוף Firebase, Extensions Hub ו-Firebase CLI.

PREINSTALL.md

בקובץ זה, ספק מידע שהמשתמש צריך לפני שהוא מתקין את התוסף שלך: תאר בקצרה מה התוסף עושה, הסבר את כל הדרישות המוקדמות, וספק למשתמש מידע על השלכות החיוב של התקנת התוסף. אם יש לך אתר עם מידע נוסף, זה גם מקום טוב לקשר אותו.

הטקסט של קובץ זה מוצג למשתמש ב- Extensions Hub ועל ידי הפקודה firebase ext:info .

להלן דוגמה לקובץ PREINSTALL:

Use this extension to automatically convert strings to upper case when added to
a specified Realtime Database path.

This extension expects a database layout like the following example:

    "messages": {
      MESSAGE_ID: {
        "original": MESSAGE_TEXT
      },
      MESSAGE_ID: {
        "original": MESSAGE_TEXT
      },
    }

When you create new string records, this extension creates a new sibling record
with upper-cased text:

    MESSAGE_ID: {
      "original": MESSAGE_TEXT,
      "upper": UPPERCASE_MESSAGE_TEXT,
    }

#### Additional setup

Before installing this extension, make sure that you've
[set up Realtime Database](https://firebase.google.com/docs/database/quickstart)
in your Firebase project.

#### Billing

To install an extension, your project must be on the
[Blaze (pay as you go) plan](https://firebase.google.com/pricing).

- This extension uses other Firebase and Google Cloud Platform services, which
  have associated charges if you exceed the service's no-cost tier:
  - Realtime Database
  - Cloud Functions (Node.js 10+ runtime)
    [See FAQs](https://firebase.google.com/support/faq#extensions-pricing)
- If you enable events,
  [Eventarc fees apply](https://cloud.google.com/eventarc/pricing).

POSTINSTALL.md

קובץ זה מכיל מידע שימושי למשתמשים לאחר שהתקינו בהצלחה את התוסף שלך: לדוגמה, שלבי מעקב, דוגמה של התוסף בפעולה וכן הלאה.

התוכן של POSTINSTALL.md מוצג במסוף Firebase לאחר הגדרת התוסף והתקנתו. אתה יכול להתייחס לפרמטרים של משתמש בקובץ זה והם יוחלפו בערכים המוגדרים.

להלן דוגמה של קובץ לאחר ההתקנה עבור סיומת ההדרכה:

### See it in action

You can test out this extension right away!

1.  Go to your
    [Realtime Database dashboard](https://console.firebase.google.com/project/${param:PROJECT_ID}/database/${param:PROJECT_ID}/data) in the Firebase console.

1.  Add a message string to a path that matches the pattern `${param:MESSAGE_PATH}`.

1.  In a few seconds, you'll see a sibling node named `upper` that contains the
    message in upper case.

### Using the extension

We recommend adding data by pushing -- for example,
`firebase.database().ref().push()` -- because pushing assigns an automatically
generated ID to the node in the database. During retrieval, these nodes are
guaranteed to be ordered by the time they were added. Learn more about reading
and writing data for your platform (iOS, Android, or Web) in the
[Realtime Database documentation](https://firebase.google.com/docs/database/).

### Monitoring

As a best practice, you can
[monitor the activity](https://firebase.google.com/docs/extensions/manage-installed-extensions#monitor)
of your installed extension, including checks on its health, usage, and logs.

CHANGELOG.md

עליך גם לתעד את השינויים שאתה מבצע בין מהדורות של הרחבה בקובץ CHANGELOG.md .

מכיוון שהתוסף לדוגמה מעולם לא פורסם בעבר, ביומן השינויים יש רק ערך אחד:

## Version 0.0.1

Initial release of the _Convert messages to upper case_ extension.

README.md

רוב ההרחבות מספקות גם קובץ readme לטובת המשתמשים המבקרים במאגר התוסף. אתה יכול לכתוב את הקובץ הזה ביד או ליצור קרא אותי באמצעות הפקודה.

לצורך מדריך זה, דלג על כתיבת קובץ readme.

תיעוד נוסף

התיעוד שנדון לעיל הוא קבוצת התיעוד המינימלית שאתה צריך לספק למשתמשים. הרחבות רבות דורשות תיעוד מפורט יותר כדי שהמשתמשים יוכלו להשתמש בהן בהצלחה. כאשר זה המקרה, עליך לכתוב תיעוד נוסף ולארח אותו במקום שאליו תוכל להפנות משתמשים.

לצורך מדריך זה, דלג על כתיבת תיעוד נרחב יותר.

11. פרסם ב- Extensions Hub

כעת, כשהתוסף שלך הושלם ומתועד, אתה מוכן לשתף אותו עם העולם ב- Extensions Hub. אבל מכיוון שזוהי רק הדרכה, אל תעשה זאת. עבור והתחל לכתוב תוסף משלך באמצעות מה שלמדת כאן ובשאר התיעוד של המוציאים לאור של Firebase Extensions, ועל ידי בחינת המקור של התוספים הרשמיים, שנכתבו על ידי Firebase.

כשתהיה מוכן לפרסם את עבודתך ב- Extensions Hub, כך תעשה זאת:

  1. אם אתה מפרסם את התוסף הראשון שלך, הירשם כמוציא לאור של הרחבה . כאשר אתה נרשם כמפרסם תוספים, אתה יוצר מזהה בעל אתר המאפשר למשתמשים לזהות אותך במהירות כמחבר התוספים שלך.
  2. ארח את קוד המקור של התוסף שלך במיקום הניתן לאימות ציבורית. כאשר הקוד שלך זמין ממקור שניתן לאמת, Firebase יכול לפרסם את התוסף שלך ישירות ממיקום זה. פעולה זו עוזרת להבטיח שאתה מפרסם את הגרסה המשוחררת של התוסף שלך, ועוזרת למשתמשים בכך שהם מאפשרים להם לבחון את הקוד שהם מתקינים בפרויקטים שלהם.

    נכון לעכשיו, המשמעות היא הפיכת התוסף שלך לזמין במאגר GitHub ציבורי.

  3. העלה את התוסף שלך אל Extensions Hub באמצעות פקודת firebase ext:dev:upload .

  4. עבור למרכז השליטה של ​​בעל האתר שלך במסוף Firebase, מצא את התוסף שהעלית זה עתה ולחץ על "פרסם לרכזת התוספים". זה מבקש בדיקה מצוות הביקורת שלנו, שעשוי להימשך כמה ימים. אם תאושר, ההרחבה תפורסם ב- Extensions Hub. אם נדחה, תקבל הודעה המסבירה את הסיבה; לאחר מכן תוכל לטפל בבעיות שדווחו ולהגיש מחדש לבדיקה.