הוספת הוּקים (hooks) של משתמשים לתוסף

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

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

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

תוסף יכול להשתמש באחת מהשיטות או בשתיהן.

אירועי Eventarc

כדי לפרסם אירועים מתוסף:

  1. צריך להצהיר על סוגי האירועים שמפרסמים בקובץ extension.yaml:

    events:
      - type: publisher-id.extension-name.version.event-name
        description: event-description
      - type: publisher-id.extension-name.version.another-event-name
        description: another-event-description
    

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

    לדוגמה, התוסף storage-resize-images מכריז על סוג אירוע יחיד:

    events:
      - type: firebase.extensions.storage-resize-images.v1.complete
        description: |
          Occurs when image resizing completes. The event will contain further
          details about specific formats and sizes.
    

    המשתמשים יוכלו לבחור לאילו אירועים להירשם כשהם יותקנו את התוסף.

  2. בפונקציות של התוסף, מייבאים את Eventarc API מה-Admin SDK ומפעילים ערוץ אירועים באמצעות הגדרות ההתקנה של המשתמש. ההגדרות האלה נחשפות באמצעות משתני הסביבה הבאים:

    • EVENTARC_CHANNEL: השם המלא של ערוץ Eventarc שאליו המשתמש בחר לפרסם אירועים.
    • EXT_SELECTED_EVENTS: רשימה מופרדת בפסיקים של סוגי האירועים שהמשתמש בחר לפרסם. כשמאתחלים ערוץ עם הערך הזה, ערכת Admin SDK מסננת באופן אוטומטי אירועים שהמשתמש לא בחר.
    • EVENTARC_CLOUD_EVENT_SOURCE: מזהה המקור של אירוע ב-Cloud. ערכת ה-SDK לניהול מעבירה את הערך הזה באופן אוטומטי בשדה source של אירועים שפורסמו. בדרך כלל אין צורך להשתמש במשתנה הזה באופן מפורש.

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

    import * as admin from "firebase-admin";
    import {getEventarc} from 'firebase-admin/eventarc';
    
    admin.initializeApp();
    
    // 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,
      });
    
  3. מפרסמים אירועים בערוץ בנקודות שבתוסף שרוצים לחשוף למשתמשים. לדוגמה:

    // If events are enabled, publish a `complete` event to the configured
    // channel.
    eventChannel && eventChannel.publish({
        type: 'firebase.extensions.storage-resize-images.v1.complete',
        subject: filename,  // the name of the original file
        data: {
          // ...
        }
    });
    
  4. מתעדים את האירועים שתפרסמו בקובץ PREINSTALL או בקובץ POSTINSTALL.

    בכל אירוע צריך לתעד את הפרטים הבאים:

    • המטרה שלשמה הוא נועד
    • הנקודה בלוגיקה של התוסף שבה הוא פועל
    • נתוני הפלט שהוא כולל
    • התנאים לביצוע שלה

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

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

לדוגמה, בדוגמה הבאה התמונה המקורית נמחקת אחרי שמשנה את הגודל שלה. שימו לב שבמקרה הזה נעשה שימוש במאפיין subject של האירוע, שהוא שם הקובץ המקורי של התמונה.

exports.onimageresized = onCustomEventPublished(
    "firebase.extensions.storage-resize-images.v1.complete",
    (event) => {
      logger.info("Received image resize completed event", event);
      // For example, delete the original.
      return admin.storage()
          .bucket("my-project.appspot.com")
          .file(event.subject)
          .delete();
    });

מידע נוסף זמין במאמר טריגרים של אירועים בהתאמה אישית.

דוגמה

התוסף הרשמי לשינוי גודל תמונות מספק הוק אסינכררוני על ידי פרסום ב-Eventarc אחרי שינוי גודל התמונה.

קטעי הוק (hooks) סינכרוניים

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

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

כדי לחשוף הוק סינכרוני:

  1. מוסיפים לתוסף פרמטר שמאפשר למשתמשים להגדיר את התוסף עם כתובת ה-URL של הפונקציה המותאמת אישית של Cloud Functions. לדוגמה:

    - param: PREPROCESSING_FUNCTION
      label: Pre-processing function URL
      description: >
        An HTTPS callable function that will be called to transform the input data
        before it is processed by this function.
      type: string
      example: https://us-west1-my-project-id.cloudfunctions.net/preprocessData
      required: false
    
  2. בנקודה שבה רוצים לחשוף את ה-hook בתוסף, צריך להפעיל את הפונקציה באמצעות כתובת ה-URL שלה. לדוגמה:

    const functions = require('firebase-functions/v1');
    const fetch = require('node-fetch');
    
    const preprocessFunctionURL = process.env.PREPROCESSING_FUNCTION;
    
    exports.yourFunctionName = functions.firestore.document("collection/{doc_id}")
        .onWrite((change, context) => {
          // PREPROCESSING_FUNCTION hook begins here.
          // If a preprocessing function is defined, call it before continuing.
          if (preprocessFunctionURL) {
            try {
              await fetch(preprocessFunctionURL); // Could also be a POST request if you want to send data.
            } catch (e) {
              // Preprocessing failure causes the function to fail.
              functions.logger.error("Preprocessor error:", e);
              return;
            }
          }
          // End of PREPROCESSING_FUNCTION hook.
    
          // Main function logic follows.
          // ...
        });
    
  3. רושמים בצד את כל ה-hooks שזמינים בקובץ PREINSTALL או PostINSTALL.

    עבור כל תוכן הוק (hook), מתעדים את הפרטים הבאים:

    • המטרה שלשמה הוא נועד
    • הנקודה בלוגיקה של התוסף שבה הוא פועל
    • הקלטים והפלטים הצפויים שלו
    • התנאים (או האפשרויות) לביצוע שלו

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

דוגמה

תוסף החיפוש של Algolia מספק וו Hook סינכרוני כדי להפעיל פונקציית טרנספורמציה שהמשתמש סיפק לפני הכתיבה ב-Algolia.