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

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

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

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

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

אירועים ב-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 Event. ‫Admin 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.

    לכל אירוע, מתעדים את הפרטים הבאים:

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

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

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

לדוגמה, בדוגמה הבאה התמונה המקורית נמחקת אחרי שהגודל שלה משתנה. שימו לב שבמטפל הזה נעשה שימוש במאפיין 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.firebasestorage.app")
          .file(event.subject)
          .delete();
    });

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

דוגמה

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

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

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

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

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

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

    - 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 Search מספק וו סינכרוני לקריאה לפונקציית טרנספורמציה שסופקה על ידי המשתמש לפני הכתיבה ל-Algolia.