البدء في إنشاء إضافة

تُطلعك هذه الصفحة على الخطوات المطلوبة لإنشاء منصة Firebase بسيطة الإضافة التي يمكنك تثبيتها في مشاريعك أو مشاركتها مع الآخرين هذا النمط مثال بسيط لإحدى إضافات Firebase ستراقب قاعدة البيانات في الوقت الفعلي الرسائل وتحويلها إلى أحرف كبيرة.

1- إعداد بيئتك وتهيئة مشروع

قبل البدء في إنشاء إضافة، يجب إعداد إصدار البيئة باستخدام الأدوات المطلوبة.

  1. ثبِّت الإصدار 16 من Node.js أو إصدار أحدث. وتتمثل إحدى طرق تثبيت Node في استخدام nvm (أو nvm-نوافذ).

  2. ثبِّت أحدث إصدار من واجهة سطر الأوامر في Firebase أو حدِّثه. إلى التثبيت أو التحديث باستخدام npm، شغِّل الأمر التالي:

    npm install -g firebase-tools
    

استخدِم الآن واجهة سطر الأوامر في Firebase لإعداد مشروع إضافة جديد:

  1. أنشئ دليلاً للإضافة وcd فيه:

    mkdir rtdb-uppercase-messages && cd rtdb-uppercase-messages
    
  2. شغِّل الأمر ext:dev:init في واجهة سطر الأوامر في Firebase:

    firebase ext:dev:init
    

    اختر لغة JavaScript كلغة للدوال عندما يُطلب منك ذلك (لكن عليك ملاحظة يمكنك أيضًا استخدام TypeScript عند إعداد إضافتك الخاصة)، عندما يُطلب منك تثبيت التبعيات، أجب بـ "نعم". (اقبل الإعدادات الافتراضية وأي خيارات أخرى). سيقوم هذا الأمر بإعداد قاعدة رموز برمجية للنظام الأساسي إضافة جديدة، يمكنك من خلالها البدء في تطوير إضافتك.

2- جرِّب نموذج الإضافة باستخدام المحاكي.

عندما بدأ واجهة سطر الأوامر في Firebase دليل الإضافات الجديد، أنشأ مثال للدالة البسيطة ودليل integration-tests الذي يحتوي على الملفات اللازمة لتشغيل إضافة باستخدام مجموعة محاكي Firebase.

يمكنك تجربة تشغيل الإضافة النموذجية في المحاكي:

  1. التغيير إلى الدليل integration-tests:

    cd functions/integration-tests
    
  2. بدء المحاكي من خلال مشروع تجريبي:

    firebase emulators:start --project=demo-test
    

    يحمّل المحاكي الإضافة في "نموذج وهمي" محدد مسبقًا المشروع (demo-test). تتكون الإضافة حتى الآن من طلب HTTP واحد يتم تشغيله الدالة greetTheWorld، والتي تُرجع "hello world" الرسالة عند الوصول إليه.

  3. أثناء تشغيل المحاكي، جرِّب greetTheWorld للإضافة. بالانتقال إلى عنوان URL الذي تمت طباعته عند بدء تشغيله.

    يعرض متصفحك الرسالة "مرحبًا بالعالم من تحية العالم".

  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. كتابة دالة Cloud وتعريفها كمورد للإضافة

يمكنك الآن البدء في كتابة بعض التعليمات البرمجية. في هذه الخطوة، ستكتب السحابة هي الوظيفة التي تؤدي المهمة الأساسية لإضافتك، وهي لمشاهدة الرسائل في الوقت الفعلي وتحويلها إلى أحرف كبيرة.

  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 مثال. في الأقسام التالية، ستُحسِّن هذه الإضافة باستخدام الميزات الإضافية. بعد ذلك، ستصبح الإضافة جاهزة للتوزيع على وأخيرًا، تعرّف على كيفية نشر إضافتك على "مركز الإضافات".

5- تعريف واجهات برمجة التطبيقات والأدوار

يمنح Firebase كل مثيل من الإضافة المُثبَّتة إمكانية وصول محدود إلى وبياناته باستخدام حساب خدمة لكل مثيل. يحتوي كل حساب على الحد الأدنى من مجموعة الأذونات اللازمة للتشغيل. لهذا السبب، يجب عليك الإفصاح صراحةً عن أي أدوار لإدارة الهوية وإمكانية الوصول تطلبها الإضافة عندما يثبّت المستخدمون إضافتك، سيُنشئ Firebase حساب خدمة باستخدام هذه الأدوار الممنوحة وتستخدمه لتشغيل الإضافة.

ليس عليك الإفصاح عن الأدوار لبدء أحداث منتج، ولكن عليك الإعلان عن دور للتعامل معه بطريقة أخرى. نظرًا لأن الدالة التي المضافة في الخطوة الأخيرة إلى قاعدة بيانات الوقت الفعلي، تحتاج إلى إضافة البيان التالي إلى extension.yaml:

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

بالمثل، أنت تُعلن عن واجهات Google APIs التي تستخدمها إحدى الإضافات في apis. . عند تثبيت المستخدمين للإضافة، سيتم سؤالهم عمّا إذا كانوا يريدون ذلك. لتفعيل واجهات برمجة التطبيقات هذه تلقائيًا لمشروعهم. عادةً ما يكون هذا فقط ضرورية لواجهات Google APIs غير التابعة لـ Firebase، ولا يلزم استخدامها في هذا الدليل.

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 يخدم فقط عندما يتم نشر إحدى الدوال السحابية كجزء من إحدى الإضافات، فإنها يستخدم تعريف المشغِّل من ملف 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 باعتباره لغة دوال Cloud، وتثبيت الموارد المطلوبة. هذا النمط مشروع المستخدم الذي تم تثبيت إضافتك عليه.

  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 على ميزة تُعرف باسم عناصر الجذب للأحداث في مراحل النشاط يمكنك استخدامها لتشغيل الإجراءات عند تثبيت الإضافة أو تحديثها أو تمت إعادة الضبط. في هذا القسم، ستستخدم عناصر الجذب للأحداث في مراحل النشاط لإضافة معلومات سابقة قاعدة بيانات الرسائل الحالية للمشروع برسائل كبيرة عندما ينقر بتثبيت إضافتك.

تستخدم إضافات Firebase "مهام Google" لتشغيل معالِجات أحداث مراحل النشاط. إِنْتَ وتحديد معالِجات الأحداث باستخدام دوال السحابة كلما حدث مثيل إذا كانت الإضافة تصل إلى أحد أحداث مراحل النشاط المتوافقة، إذا حدّدت ستتم إضافة المعالج إلى قائمة انتظار مهام السحابة الإلكترونية. ستجري خدمة "مهام Google" بعد ذلك تنفيذ المعالج بشكل غير متزامن. أثناء تشغيل معالج أحداث مراحل النشاط، ستبلِغ "وحدة تحكُّم 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 تتطلب وظائف السحابة الإلكترونية لبرنامج 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 الإعداد في دليل extensions وتسجيل مصدر الإضافة الموقع في ملف firebase.json. بشكل جماعي، يعد هذان السجلان الذي يُطلق عليه بيان الإضافات. يمكن للمستخدمين استخدام البيان لحفظ تهيئة الإضافات ونشرها في مشاريع مختلفة.

  4. فعِّل إعدادات الإضافة في مشروعك المنشور:

    firebase deploy --only extensions
    

إذا سارت الأمور على ما يرام، من المفترض أن يحمِّل واجهة سطر الأوامر في Firebase إضافتك إلى مشروعك وتثبيتها. بعد اكتمال التثبيت، سيتم تشغيل مهمة إعادة التعبئة سيتم تحديث قاعدة البيانات بالرسائل التي تحتوي على أحرف كبيرة في غضون بضع دقائق. إضافة البعض عُقد جديدة في قاعدة بيانات الرسائل والتأكد من أن الإضافة تعمل أيضًا للرسائل الجديدة.

10. كتابة المستندات

قبل مشاركة الإضافة مع المستخدمين، تأكّد من تقديم معلومات من أجل نجاحها.

عند إعداد مشروع الإضافة، أنشأ واجهة سطر الأوامر في Firebase مقتطفًا نُسخًا من الحد الأدنى من الوثائق المطلوبة. تحديث هذه الملفات إلى أن تكون تعكس الامتداد الذي أنشأته.

item.yaml

لقد كنت تعدِّل هذا الملف من قبل، لأنّك طوّرته هذه الإضافة، لذا وليس عليك إجراء أي تحديثات أخرى في الوقت الحالي.

ومع ذلك، لا تغفل أهمية الوثائق الواردة في هذا الملف. بالإضافة إلى المعلومات التعريفية المهمة للإضافة - الاسم الوصف والمؤلف وموقع المستودع الرسمي والمؤلفextension.yaml يحتوي على وثائق موجهة للمستخدمين لكل مورد وقابل للتهيئة . يتم عرض هذه المعلومات للمستخدمين في وحدة تحكُّم Firebase مركز الإضافات وواجهة سطر الأوامر في Firebase

PREINSTALL.md

في هذا الملف، قدم المعلومات التي يحتاجها المستخدم قبل تثبيت الإضافة: وصف بإيجاز وظيفة الإضافة وشرح أي متطلبات أساسية وتزويد المستخدم بمعلومات حول الآثار المترتبة على الفوترة نتيجة تثبيت الإضافة. إذا كان لديك موقع ويب يحتوي على معلومات إضافية، مكانًا جيدًا لربطه.

يتم عرض نص هذا الملف للمستخدم في "مركز الإضافات" ومن خلال الأمر 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

توفر معظم الإضافات أيضًا ملفًا تمهيديًا لصالح المستخدمين الذين يزورون مستودع الإضافة. يمكنك كتابة هذا الملف يدويًا أو إنشاء رمز قراءة باستخدام الأمر.

لأغراض هذا الدليل، يمكنك تخطي كتابة ملف تمهيدي.

مستندات إضافية

الوثائق التي تمت مناقشتها أعلاه هي الحد الأدنى من مجموعة الوثائق التي ينبغي لك تزويد المستخدمين بها. تتطلب العديد من الإضافات وثائق أكثر تفصيلاً للمستخدمين استخدامها بنجاح. في هذه الحالة، يجب عليك كتابة معلومات التوثيق واستضافتها في مكان يمكنك توجيه المستخدمين إليه.

لأغراض هذا الدليل، يمكنك تخطي كتابة المزيد من المستندات الشاملة.

11- النشر في "مركز الإضافات"

الآن وبعد اكتمال الرمز البرمجي وتوثيقه، أصبحت جاهزًا لمشاركة العالم على "مركز الإضافات". ولكن بما أن هذا مجرد برنامج تعليمي، فلا القيام بذلك في الواقع. ابدأ في كتابة إضافتك الخاصة باستخدام ما كما تعلمناها هنا وفي بقية مستندات الناشرين المتعلقة بإضافات Firebase، ومن خلال فحص مصدر الإضافات الرسمية المكتوبة من Firebase

عند الاستعداد لنشر عملك على "مركز الإضافات"، يمكنك الاطّلاع على الإجراءات التالية: فهو:

  1. إذا كنت تنشر الإضافة الأولى التسجيل كناشر للإضافة فعندما بالتسجيل كناشر للإضافات، يمكنك إنشاء رقم تعريفي للناشر يتيح يمكن للمستخدمين التعرّف عليك بسرعة كمؤلف إضافاتك.
  2. استضِف رمز المصدر الخاص بإضافتك في موقع يمكن التحقّق منه بشكل علني. فعندما أن الرمز البرمجي متاح من مصدر يمكن التحقق منه، فيمكن لمنصّة Firebase نشر الإضافة من هذا الموقع مباشرةً. يساعد القيام بذلك في التأكد من أنك نشر الإصدار الذي تم إصداره حاليًا من إضافتك، ومساعدة المستخدمين عن طريق السماح لهم بفحص الرمز الذي يثبّتونه في مشروعاتهم.

    ويعني هذا في الوقت الحالي إتاحة إضافتك في GitHub متاح للجميع. المستودع.

  3. تحميل إضافتك إلى "مركز الإضافات" باستخدام "firebase ext:dev:upload" الأمر.

  4. انتقِل إلى لوحة بيانات الناشر في "وحدة تحكُّم Firebase" وابحث عن الإضافة. الذي حمَّلته للتو وانقر على "النشر على مركز الإضافات". يتطلب هذا مراجعة من فريق المراجعة، وقد يستغرق ذلك بضعة أيام. في حال الموافقة، يجب استيفاء سيتم نشر الإضافة في "مركز الإضافات". في حال الرفض، ستتلقّى رسالة تشرح السبب يمكنك بعد ذلك معالجة المشكلات التي تم الإبلاغ عنها إعادة إرساله للمراجعة.