ترشدك هذه الصفحة عبر الخطوات المطلوبة لإنشاء ملحق Firebase بسيط، والذي يمكنك تثبيته في مشاريعك أو مشاركته مع الآخرين. هذا المثال البسيط لامتداد Firebase سوف يراقب قاعدة بيانات Realtime الخاصة بك للرسائل ويحولها إلى أحرف كبيرة.
1. قم بإعداد البيئة الخاصة بك وتهيئة المشروع
قبل أن تتمكن من البدء في إنشاء ملحق، ستحتاج إلى إعداد بيئة بناء باستخدام الأدوات المطلوبة.
قم بتثبيت Node.js 16 أو الأحدث. إحدى طرق تثبيت Node هي استخدام nvm (أو nvm-windows ).
قم بالتثبيت أو التحديث إلى أحدث إصدار من Firebase CLI . للتثبيت أو التحديث باستخدام
npm
، قم بتشغيل هذا الأمر:npm install -g firebase-tools
استخدم الآن Firebase CLI لتهيئة مشروع ملحق جديد:
قم بإنشاء دليل للامتداد الخاص بك
cd
فيه:mkdir rtdb-uppercase-messages && cd rtdb-uppercase-messages
قم بتشغيل الأمر
ext:dev:init
الخاص بـ Firebase CLI:firebase ext:dev:init
عندما يُطلب منك ذلك، اختر JavaScript كلغة للوظائف (ولكن لاحظ أنه يمكنك أيضًا استخدام TypeScript عند تطوير الامتداد الخاص بك)، وعندما يُطلب منك تثبيت التبعيات، أجب بـ "نعم". (اقبل الإعدادات الافتراضية لأي خيارات أخرى.) سيقوم هذا الأمر بإعداد قاعدة تعليمات برمجية هيكلية لامتداد جديد، يمكنك من خلاله البدء في تطوير الامتداد الخاص بك.
استخدم firebase ext:dev:init
لتهيئة دليل ملحق جديد.
2. جرب ملحق المثال باستخدام المحاكي
عندما قامت واجهة سطر أوامر Firebase بتهيئة دليل الامتدادات الجديد، قامت بإنشاء وظيفة نموذجية بسيطة ودليل integration-tests
الذي يحتوي على الملفات الضرورية لتشغيل ملحق باستخدام مجموعة محاكي Firebase.
حاول تشغيل ملحق المثال في المحاكي:
التغيير إلى دليل
integration-tests
:cd functions/integration-tests
ابدأ تشغيل المحاكي بمشروع تجريبي:
firebase emulators:start --project=demo-test
يقوم المحاكي بتحميل الامتداد في مشروع "وهمي" محدد مسبقًا (
demo-test
). يتألف الامتداد حتى الآن من دالة واحدة يتم تشغيلها بواسطة HTTP،greetTheWorld
، والتي تعرض رسالة "hello World" عند الوصول إليها.مع استمرار تشغيل المحاكي، جرب وظيفة
greetTheWorld
الخاصة بالامتداد عن طريق زيارة عنوان URL الذي طبعه عند بدء تشغيله.يعرض متصفحك الرسالة "Hello World from Greeting-the-World".
الكود المصدري لهذه الوظيفة موجود في دليل
functions
الامتداد. افتح المصدر في المحرر أو IDE الذي تختاره:وظائف/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); });
أثناء تشغيل المحاكي، سيقوم تلقائيًا بإعادة تحميل أي تغييرات تجريها على كود الوظائف الخاص بك. حاول إجراء تغيير بسيط على وظيفة
greetTheWorld
:وظائف/index.js
const greeting = `${consumerProvidedGreeting} everyone, from ${instanceId}`;
احفظ تغييراتك. سيقوم المحاكي بإعادة تحميل التعليمات البرمجية الخاصة بك، والآن، عند زيارة عنوان URL الخاص بالوظيفة، سترى التحية المحدثة.
يمكن أن يؤدي استخدام محاكي الإضافات إلى تسريع عملية التطوير من خلال السماح لك باختبار التعليمات البرمجية الخاصة بك وتكرارها بسرعة.
معلومات اكثر
تعرف على المزيد حول استخدام محاكي الإضافات .
3. أضف المعلومات الأساسية إلى الامتداد.yaml
الآن بعد أن تم إعداد بيئة التطوير وتشغيل محاكي الامتدادات، يمكنك البدء في كتابة الامتداد الخاص بك.
كخطوة أولى متواضعة، قم بتحرير البيانات التعريفية للإضافة المحددة مسبقًا لتعكس الامتداد الذي تريد كتابته بدلاً من greet-the-world
. يتم تخزين هذه البيانات الوصفية في ملف extension.yaml
.
افتح
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 الأساسي الذي يعمل عليه الامتداد، متبوعًا بوصف لما يفعله الامتداد. يجب عليك استخدام نفس الاتفاقية في ملحقاتك الخاصة.نظرًا لأنك قمت بتغيير اسم الامتداد الخاص بك، فيجب عليك أيضًا تحديث تكوين المحاكي الخاص بك بالاسم الجديد:
- في
functions/integration-tests/firebase.json
، قم بتغييرgreet-the-world
إلىrtdb-uppercase-messages
. - أعد
functions/integration-tests/extensions/greet-the-world.env
إلىfunctions/integration-tests/extensions/rtdb-uppercase-messages.env
.
- في
لا تزال هناك بعض بقايا ملحق greet-the-world
متبقية في رمز الامتداد الخاص بك، لكن اتركها الآن. ستقوم بتحديث تلك في الأقسام القليلة القادمة.
يحتوي الملف
extension.yaml
على بيانات وصفية حول امتدادك. أبسط هذه البيانات الوصفية هو اسم الامتداد الخاص بك ووصف ما يفعله.قم بتسمية ملحقاتك بالتنسيق التالي:
<firebase-product>-<description-of-tasks-performed>
.
معلومات اكثر
يحتوي مرجع extension.yaml
على المواصفات الكاملة للملف؛ ومع ذلك، ستناقش هذه الوثائق الاستخدامات المحددة لهذا الملف حسب حاجتك لاستخدامها.
4. اكتب وظيفة سحابية وأعلنها كمورد ملحق
الآن يمكنك البدء في كتابة بعض التعليمات البرمجية. في هذه الخطوة، ستكتب وظيفة سحابية تؤدي المهمة الأساسية لامتدادك، وهي مراقبة قاعدة بيانات الوقت الفعلي الخاصة بك للرسائل وتحويلها إلى أحرف كبيرة.
افتح المصدر لوظائف الامتداد (في دليل
functions
الامتداد) في المحرر أو IDE الذي تختاره. استبدل محتوياته بما يلي:وظائف/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", … }
يجب الإعلان عن كل وظيفة في ملحقك في ملف
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"
نظرًا لأن ملحقك يستخدم الآن Realtime Database كمشغل، فأنت بحاجة إلى تحديث تكوين المحاكي لتشغيل محاكي RTDB جنبًا إلى جنب مع محاكي Cloud Functions:
إذا كان المحاكي لا يزال قيد التشغيل، فأوقفه بالضغط على Ctrl-C.
من دليل
functions/integration-tests
، قم بتشغيل الأمر التالي:firebase init emulators
عندما يُطلب منك ذلك، قم بتخطي إعداد المشروع الافتراضي، ثم حدد محاكيات الوظائف وقاعدة البيانات. اقبل المنافذ الافتراضية واسمح لأداة الإعداد بتنزيل أي ملفات مطلوبة.
أعد تشغيل المحاكي:
firebase emulators:start --project=demo-test
جرب الامتداد المحدث:
افتح واجهة مستخدم محاكي قاعدة البيانات باستخدام الرابط الذي طبعه المحاكي عند بدء تشغيله.
تحرير العقدة الجذرية لقاعدة البيانات:
- المجال :
messages
- النوع:
json
- القيمة:
{"11": {"original": "recipe"}}
إذا تم إعداد كل شيء بشكل صحيح، فعند حفظ تغييرات قاعدة البيانات الخاصة بك، يجب أن تقوم وظيفة
makeuppercase
الخاصة بالملحق بتشغيل سجل فرعي وإضافته إلى الرسالة 11 بالمحتويات"upper": "RECIPE"
. ألقِ نظرة على السجلات وعلامات تبويب قاعدة البيانات الخاصة بواجهة مستخدم المحاكي لتأكيد النتائج المتوقعة.- المجال :
حاول إضافة المزيد من العناصر الفرعية إلى عقدة
messages
({"original":"any text"}
). كلما قمت بإضافة سجل جديد، يجب أن يضيف الامتداد حقلاًuppercase
يحتوي على محتويات الحقلoriginal
.
لديك الآن امتداد كامل، وإن كان بسيطًا، يعمل على مثيل RTDB. في الأقسام التالية، ستقوم بتحسين هذا الامتداد مع بعض الميزات الإضافية. بعد ذلك، ستصبح الامتداد جاهزًا للتوزيع على الآخرين، وأخيرًا، ستتعرف على كيفية نشر الامتداد الخاص بك على Extensions Hub.
- يجب تعريف الوظائف التي تشكل منطق الامتداد الخاص بك على أنها رمز Cloud Functions والإعلان عنها كمورد ملحق في ملف
extension.yaml
. - يمكنك كتابة الوظائف التي يتم تشغيلها عند الوصول إلى نقاط نهاية HTTP، أو استجابة للأحداث الصادرة عن منتجات Firebase ومنتجات Google Cloud والإضافات الأخرى.
معلومات اكثر
- تعرف على المزيد حول كتابة وظائف السحابة للملحقات ، بما في ذلك المزيد حول مشغلات الأحداث المدعومة.
- يحتوي مرجع
extension.yaml
على المواصفات الكاملة للملف؛ ومع ذلك، ستناقش هذه الوثائق الاستخدامات المحددة لهذا الملف حسب حاجتك لاستخدامها. - تحتوي وثائق Cloud Functions for Firebase على معلومات عامة حول استخدام Cloud Functions، وليست خاصة بملحقات Firebase.
5. أعلن عن واجهات برمجة التطبيقات والأدوار
يمنح Firebase كل مثيل لملحق مثبت وصولاً محدودًا إلى المشروع وبياناته باستخدام حساب خدمة لكل مثيل. يحتوي كل حساب على الحد الأدنى من الأذونات اللازمة للتشغيل. لهذا السبب، يجب عليك الإعلان بوضوح عن أي أدوار IAM يتطلبها ملحقك؛ عندما يقوم المستخدمون بتثبيت ملحقك، يقوم Firebase بإنشاء حساب خدمة مع منح هذه الأدوار ويستخدمه لتشغيل الملحق.
لا تحتاج إلى الإعلان عن الأدوار لتشغيل أحداث المنتج، ولكنك تحتاج إلى الإعلان عن دور للتفاعل معه بطريقة أخرى. نظرًا لأن الوظيفة التي أضفتها في الخطوة الأخيرة تكتب في قاعدة بيانات Realtime، فأنت بحاجة إلى إضافة التصريح التالي إلى extension.yaml
:
roles:
- role: firebasedatabase.admin
reason: Allows the extension to write to RTDB.
وبالمثل، فإنك تعلن عن واجهات برمجة تطبيقات Google التي يستخدمها الملحق في حقل واجهة apis
. عندما يقوم المستخدمون بتثبيت ملحقك، سيتم سؤالهم عما إذا كانوا يريدون تمكين واجهات برمجة التطبيقات هذه تلقائيًا لمشروعهم. عادةً ما يكون هذا ضروريًا فقط لواجهات برمجة تطبيقات Google غير التابعة لـ Firebase، وهو غير مطلوب في هذا الدليل.
- قم بتعريف أي دور IAM يحتاجه الامتداد الخاص بك في حقل
roles
extensions.yaml
. عند التثبيت، يتم منح الملحقات هذه الأدوار تلقائيًا. - قم بتعريف أي واجهات برمجة تطبيقات Google التي يحتاجها ملحقك في حقل واجهة
apis
التطبيقات الخاص بـextensions.yaml
. عندما يقوم المستخدمون بتثبيت ملحقك، يمكنهم اختيار تمكين واجهات برمجة التطبيقات هذه تلقائيًا لمشروعهم. - لأغراض التوثيق، أعلن عن أي واجهات برمجة تطبيقات غير تابعة لـ Google تحتاجها الإضافة في حقل
externalServices
فيextensions.yaml
.
معلومات اكثر
- تعرف على المزيد حول إعداد الوصول المناسب للامتداد .
- يحتوي مرجع
extension.yaml
على المواصفات الكاملة للملف؛ ومع ذلك، ستناقش هذه الوثائق الاستخدامات المحددة لهذا الملف حسب حاجتك لاستخدامها.
6. تحديد المعلمات القابلة للتكوين بواسطة المستخدم
تقوم الوظيفة التي قمت بإنشائها في الخطوتين الأخيرتين بمراقبة موقع RTDB محدد للرسائل الواردة. في بعض الأحيان، تكون مشاهدة موقع معين هو ما تريده حقًا، كما هو الحال عندما يعمل ملحقك على بنية قاعدة بيانات تستخدمها حصريًا لامتدادك. ومع ذلك، في أغلب الأحيان، ستحتاج إلى جعل هذه القيم قابلة للتكوين بواسطة المستخدمين الذين يقومون بتثبيت ملحقك في مشاريعهم. بهذه الطريقة، يمكن للمستخدمين الاستفادة من ملحقك للعمل مع إعداد قاعدة البيانات الموجودة لديهم.
اجعل المسار الذي يشاهده الامتداد للرسائل الجديدة قابلاً للتكوين بواسطة المستخدم:
في ملف
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
يحدد هذا معلمة سلسلة جديدة سيُطلب من المستخدمين تعيينها عند تثبيت الامتداد الخاص بك.
لا يزال في الملف
extension.yaml
، ارجع إلى إعلانmakeuppercase
وقم بتغيير حقلresource
إلى ما يلي:resource: projects/_/instances/${DATABASE_INSTANCE}/refs/${param:MESSAGE_PATH}
يعد الرمز المميز
${param:MESSAGE_PATH}
مرجعًا للمعلمة التي حددتها للتو. عند تشغيل الامتداد الخاص بك، سيتم استبدال هذا الرمز المميز بأي قيمة قام المستخدم بتكوينها لتلك المعلمة، مما يؤدي إلى أن تستمع وظيفةmakeuppercase
إلى المسار الذي حدده المستخدم. يمكنك استخدام بناء الجملة هذا للإشارة إلى أي معلمة معرفة من قبل المستخدم في أي مكان فيextension.yaml
(وفيPOSTINSTALL.md
- المزيد عن ذلك لاحقًا).يمكنك أيضًا الوصول إلى المعلمات المحددة من قبل المستخدم من كود الوظائف الخاص بك.
في الوظيفة التي كتبتها في القسم الأخير، قمت بترميز المسار بشكل ثابت لمراقبة التغييرات. قم بتغيير تعريف المشغل للإشارة إلى القيمة المعرفة من قبل المستخدم بدلاً من ذلك:
وظائف/index.js
export const makeuppercase = database.ref(process.env.MESSAGE_PATH).onCreate
لاحظ أنه في Firebase Extensions، يكون هذا التغيير بغرض التوثيق فقط: عندما يتم نشر وظيفة Cloud كجزء من ملحق، فإنها تستخدم تعريف المشغل من ملف
extension.yaml
وتتجاهل القيمة المحددة في تعريف الوظيفة. ومع ذلك، من الجيد أن تقوم بتوثيق المصدر الذي تأتي منه هذه القيمة في التعليمات البرمجية الخاصة بك.قد تجد أنه من المخيب للآمال إجراء تغيير في التعليمات البرمجية ليس له أي تأثير في وقت التشغيل، ولكن الدرس المهم الذي يجب تعلمه هو أنه يمكنك الوصول إلى أي معلمة محددة من قبل المستخدم في كود الوظيفة الخاصة بك واستخدامها كقيمة عادية في منطق الوظيفة. كإشارة إلى هذه الإمكانية، أضف بيان السجل التالي لتوضيح أنك تصل بالفعل إلى القيمة التي حددها المستخدم:
وظائف/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. ...
عادةً، يُطلب من المستخدمين تقديم قيم للمعلمات عند تثبيت الامتداد. عند استخدام المحاكي للاختبار والتطوير، فإنك تتخطى عملية التثبيت، لذا تقوم بدلاً من ذلك بتوفير قيم للمعلمات المعرفة من قبل المستخدم باستخدام ملف
env
.افتح
functions/integration-tests/extensions/rtdb-uppercase-messages.env
واستبدل تعريفGREETING
بما يلي:MESSAGE_PATH=/msgs/{pushId}/original
لاحظ أن المسار أعلاه يختلف عن المسار الافتراضي وعن المسار الذي حددته مسبقًا؛ هذا فقط لتثبت لنفسك عند تجربة الامتداد المحدث أن التعريف الخاص بك أصبح ساري المفعول.
الآن، أعد تشغيل المحاكي وقم بزيارة واجهة مستخدم محاكي قاعدة البيانات مرة أخرى.
قم بتحرير العقدة الجذرية لقاعدة البيانات، باستخدام المسار الذي حددته أعلاه:
- الحقل:
msgs
- النوع:
json
- القيمة:
{"11": {"original": "recipe"}}
عندما تحفظ تغييرات قاعدة البيانات الخاصة بك، يجب أن يتم تشغيل وظيفة
makeuppercase
الخاصة بالملحق كما فعلت من قبل، ولكن يجب الآن أيضًا طباعة المعلمة المحددة من قبل المستخدم في سجل وحدة التحكم.- الحقل:
- يمكنك منح المستخدمين القدرة على تخصيص الامتداد الخاص بك ليناسب احتياجاتهم من خلال الإعلان عن المعلمات المعرفة من قبل المستخدم في ملف
extension.yaml
. يُطلب من المستخدمين تحديد هذه القيم عند تثبيت الامتداد الخاص بك. - يمكنك الرجوع إلى قيم المعلمات المعرفة من قبل المستخدم داخل ملف
extension.yaml
وفي ملفPOSTINSTALL.md
باستخدام بناء الجملة التالي:${param:PARAMETER_NAME}
- يمكنك الوصول إلى قيم المعلمات المعرفة من قبل المستخدم ضمن رمز Cloud Functions الخاص بك كمتغيرات البيئة:
process.env.PARAMETER_NAME
- عند الاختبار باستخدام المحاكي، حدد معلمات المستخدم في ملف
<extension-name>.env
.
معلومات اكثر
تعرف على المزيد حول إعداد المعلمات واستخدامها في الامتداد الخاص بك .
7. توفير خطافات الأحداث للمنطق المحدد من قبل المستخدم
لقد رأيت بالفعل، كمؤلف ملحق، كيف يمكن لمنتج Firebase تشغيل المنطق الذي توفره الإضافة: يؤدي إنشاء سجلات جديدة في قاعدة بيانات Realtime إلى تشغيل وظيفة makeuppercase
الخاصة بك. يمكن أن يكون لامتدادك علاقة مماثلة مع المستخدمين الذين قاموا بتثبيت ملحقك: يمكن أن يؤدي ملحقك إلى تشغيل المنطق الذي يحدده المستخدم .
يمكن أن يوفر الامتداد خطافات متزامنة أو خطافات غير متزامنة أو كليهما. توفر الخطافات المتزامنة للمستخدمين طريقة لأداء المهام التي تمنع إكمال إحدى وظائف الامتداد. يمكن أن يكون هذا مفيدًا، على سبيل المثال، لمنح المستخدمين طريقة لإجراء معالجة مسبقة مخصصة قبل أن يقوم الملحق بعمله.
في هذا الدليل، ستضيف رابطًا غير متزامن إلى ملحقك، مما سيمكن المستخدمين من تحديد خطوات المعالجة الخاصة بهم ليتم تشغيلها بعد أن يكتب ملحقك الرسالة الكبيرة إلى قاعدة بيانات Realtime. تستخدم الخطافات غير المتزامنة Eventarc لتشغيل وظائف محددة من قبل المستخدم. تعلن الامتدادات عن أنواع الأحداث التي تصدرها، وعندما يقوم المستخدمون بتثبيت الامتداد، فإنهم يختارون أنواع الأحداث التي يهتمون بها. إذا اختاروا حدثًا واحدًا على الأقل، فسيوفر Firebase قناة Eventarc للامتداد كجزء من عملية التثبيت . يمكن للمستخدمين بعد ذلك نشر وظائفهم السحابية الخاصة التي تستمع إلى تلك القناة ويتم تشغيلها عندما ينشر الامتداد أحداثًا جديدة.
اتبع هذه الخطوات لإضافة ربط غير متزامن:
في ملف
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
في الوقت الحالي.)في نهاية وظيفة
makeuppercase
، أضف بعض التعليمات البرمجية التي تنشر حدثًا من النوع الذي أعلنته للتو:وظائف/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
التي تحتوي على الرسائل الأصلية والأحرف الكبيرة. يمكن للوظائف المعرفة من قبل المستخدم والتي تؤدي إلى تشغيل الحدث الاستفادة من هذه المعلومات.عادةً، يتم تعريف متغيرات البيئة
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
في هذه المرحلة، تكون قد أكملت الخطوات اللازمة لإضافة ربط حدث غير متزامن إلى ملحقك.
لتجربة هذه الميزة الجديدة التي قمت بتنفيذها للتو، في الخطوات القليلة التالية، قم بدور المستخدم الذي يقوم بتثبيت الامتداد:
من دليل
functions/integration-tests
، قم بتهيئة مشروع Firebase جديد:firebase init functions
عندما يُطلب منك ذلك، ارفض إعداد مشروع افتراضي، وحدد JavaScript كلغة Cloud Functions، ثم قم بتثبيت التبعيات المطلوبة. يمثل هذا المشروع مشروع المستخدم الذي تم تثبيت ملحقك عليه.
قم بتحرير
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
، وعند تشغيله، تضيف ثلاث علامات تعجب إلى الرسالة المكتوبة بأحرف كبيرة حديثًا.أعد تشغيل المحاكي. سيقوم المحاكي بتحميل وظائف الامتداد بالإضافة إلى وظيفة ما بعد المعالجة التي حددها "المستخدم".
قم بزيارة واجهة مستخدم محاكي قاعدة البيانات وقم بتحرير العقدة الجذرية لقاعدة البيانات، باستخدام المسار الذي حددته أعلاه:
- الحقل:
msgs
- النوع:
json
- القيمة:
{"11": {"original": "recipe"}}
عندما تحفظ تغييرات قاعدة البيانات الخاصة بك، يجب أن يتم تشغيل وظيفة
makeuppercase
الخاصة بالملحق ووظيفةextraemphasis
للمستخدم بالتسلسل، مما يؤدي إلى حصول الحقلupper
على القيمةRECIPE!!!
.- الحقل:
- يمكن أن تتضمن ملحقاتك خطافات تتيح للمستخدمين إدراج منطقهم الخاص في العملية الأساسية لامتدادك.
- يمكن أن تكون خطافات المستخدم متزامنة، مما يمنع تنفيذ الامتداد حتى يكتمل. غالبًا ما تستخدم الإضافات خطافات متزامنة لتنفيذ مهام المعالجة المسبقة المحددة من قبل المستخدم.
- يمكن أيضًا أن تكون خطافات المستخدم غير متزامنة، كما في المثال أعلاه. يمكن استخدام الخطافات غير المتزامنة لتشغيل المنطق المحدد من قبل المستخدم والذي ليس ضروريًا لكي يعمل الامتداد بشكل صحيح.
معلومات اكثر
تعرف على المزيد حول إضافة الخطافات للمنطق المحدد من قبل المستخدم ، بما في ذلك الخطافات غير المتزامنة والمتزامنة.
8. قم بإضافة معالجات أحداث دورة الحياة
يقوم الامتداد الذي كتبته حتى الآن بمعالجة الرسائل عند إنشائها. ولكن ماذا لو كان لدى المستخدمين لديك بالفعل قاعدة بيانات للرسائل عند تثبيت الامتداد؟ تحتوي ملحقات Firebase على ميزة تسمى خطافات أحداث دورة الحياة والتي يمكنك استخدامها لتشغيل الإجراءات عند تثبيت ملحقك أو تحديثه أو إعادة تكوينه. في هذا القسم، ستستخدم خطافات أحداث دورة الحياة لملء قاعدة بيانات الرسائل الموجودة في المشروع برسائل بأحرف كبيرة عندما يقوم المستخدم بتثبيت ملحقك.
تستخدم ملحقات Firebase المهام السحابية لتشغيل معالجات أحداث دورة الحياة الخاصة بك. يمكنك تحديد معالجات الأحداث باستخدام Cloud Functions؛ عندما يصل مثيل ملحقك إلى أحد أحداث دورة الحياة المدعومة، إذا قمت بتحديد معالج، فسوف يضيف المعالج إلى قائمة انتظار المهام السحابية. ستقوم المهام السحابية بعد ذلك بتنفيذ المعالج بشكل غير متزامن. أثناء تشغيل معالج أحداث دورة الحياة، ستقوم وحدة تحكم Firebase بإبلاغ المستخدم بأن مثيل الامتداد لديه مهمة معالجة قيد التقدم. الأمر متروك لوظيفة المعالج الخاص بك للإبلاغ عن الحالة المستمرة وإكمال المهمة مرة أخرى إلى المستخدم.
لإضافة معالج أحداث دورة الحياة الذي يقوم بملء الرسائل الموجودة، قم بما يلي:
حدد وظيفة سحابية جديدة يتم تشغيلها بواسطة أحداث قائمة انتظار المهام:
وظائف/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."); } });
لاحظ أن الوظيفة تعالج فقط بعض السجلات قبل إضافة نفسها مرة أخرى إلى قائمة انتظار المهام. هذه إستراتيجية شائعة الاستخدام للتعامل مع مهام المعالجة التي لا يمكن إكمالها خلال نافذة المهلة الخاصة بوظيفة السحابة. نظرًا لأنه لا يمكنك التنبؤ بعدد الرسائل التي قد تكون لدى المستخدم بالفعل في قاعدة بياناته عند تثبيت ملحقك، فإن هذه الإستراتيجية مناسبة تمامًا.
في الملف
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
على الرغم من أن إعادة ملء الرسائل الموجودة أمر جيد، إلا أن الامتداد لا يزال من الممكن أن يعمل بدونه. في مثل هذه المواقف، يجب عليك جعل تشغيل معالجات أحداث دورة الحياة أمرًا اختياريًا.
للقيام بذلك، قم بإضافة معلمة جديدة إلى
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
واخرج مبكرًا إذا لم يتم تعيينها:وظائف/index.js
if (!process.env.DO_BACKFILL) { return getExtensions() .runtime() .setProcessingState("PROCESSING_COMPLETE", "Backfill skipped."); }
مع التغييرات المذكورة أعلاه، سيقوم الامتداد الآن بتحويل الرسائل الموجودة إلى أحرف كبيرة عند تثبيته.
حتى هذه اللحظة، كنت تستخدم محاكي الامتداد لتطوير الامتداد الخاص بك واختبار التغييرات المستمرة. ومع ذلك، فإن محاكي الامتداد يتخطى عملية التثبيت، لذا لاختبار معالج الأحداث onInstall
، ستحتاج إلى تثبيت الامتداد في مشروع حقيقي. وهذا أيضًا جيد، لأنه مع إضافة ميزة الملء التلقائي هذه، أصبح ملحق البرنامج التعليمي الآن مكتملًا للتعليمات البرمجية!
يتم تشغيل أحداث دورة الحياة عندما يقوم المستخدمون بتنفيذ مهام معينة لإدارة الامتدادات:
- تثبيت مثيل للامتداد
- تحديث مثيل للامتداد إلى إصدار جديد
- إعادة تكوين مثيل ملحق
يمكنك تحديد الوظائف التي يتم تشغيلها في أحداث دورة حياة ملحقك.
استخدم واجهة برمجة تطبيقات وقت تشغيل ملحق Admin SDK للإبلاغ عن حالة معالج أحداث دورة الحياة مرة أخرى إلى المستخدم. سيرى المستخدمون حالة المعالجة الحالية للملحق في وحدة تحكم Firebase.
غالبًا ما لا يمكن إكمال الوظائف التي تعمل على قاعدة البيانات بأكملها (مثل عمليات إعادة التعبئة) قبل انتهاء مهلة وظيفة السحابة. يمكنك تجنب هذه المشكلة عن طريق تقسيم مهمتك على عدة استدعاءات وظيفية.
إذا كان الملحق الخاص بك يشتمل على معالجات أحداث دورة الحياة التي ليست مهمة لكي يعمل الملحق، فيجب عليك جعل تنفيذ مستخدم المعالج قابلاً للتكوين.
معلومات اكثر
تعرف على المزيد حول التعامل مع أحداث دورة حياة ملحقك .
9. النشر في مشروع Firebase حقيقي
على الرغم من أن محاكي الامتدادات يعد أداة رائعة للتكرار السريع للامتداد أثناء التطوير، إلا أنك ستحتاج في مرحلة ما إلى تجربته في مشروع حقيقي.
للقيام بذلك، قم أولاً بإعداد مشروع جديد مع تمكين بعض الخدمات:
- في وحدة تحكم Firebase ، قم بإضافة مشروع جديد.
- قم بترقية مشروعك إلى خطة Blaze للدفع أولاً بأول. تتطلب Cloud Functions for Firebase أن يكون لمشروعك حساب فوترة، لذلك تحتاج أيضًا إلى حساب فوترة لتثبيت ملحق.
- في مشروعك الجديد، قم بتمكين قاعدة البيانات في الوقت الحقيقي .
- نظرًا لأنك تريد اختبار قدرة ملحقك على إعادة ملء البيانات الموجودة عند التثبيت، فاستورد بعض نماذج البيانات إلى مثيل قاعدة بياناتك في الوقت الفعلي:
- قم بتنزيل بعض بيانات RTDB الأولية .
- في صفحة قاعدة البيانات في الوقت الفعلي لوحدة تحكم Firebase، انقر فوق (المزيد) > استيراد JSON وحدد الملف الذي قمت بتنزيله للتو.
لتمكين وظيفة الردم من استخدام الأسلوب
orderByChild
، قم بتكوين قاعدة البيانات لفهرسة الرسائل بقيمةupper
:{ "rules": { ".read": false, ".write": false, "messages": { ".indexOn": "upper" } } }
الآن قم بتثبيت الامتداد الخاص بك من المصدر المحلي في المشروع الجديد:
قم بإنشاء دليل جديد لمشروع Firebase الخاص بك:
mkdir ~/extensions-live-test && cd ~/extensions-live-test
تهيئة مشروع Firebase في دليل العمل:
firebase init database
عند المطالبة، حدد المشروع الذي قمت بإنشائه للتو.
قم بتثبيت الامتداد في مشروع Firebase المحلي الخاص بك:
firebase ext:install /path/to/rtdb-uppercase-messages
هنا يمكنك رؤية تجربة المستخدم عند تثبيت ملحق باستخدام أداة Firebase CLI. تأكد من تحديد "نعم" عندما تسألك أداة التكوين عما إذا كنت تريد ملء قاعدة البيانات الموجودة لديك.
بعد تحديد خيارات التكوين، ستقوم واجهة سطر أوامر Firebase بحفظ التكوين الخاص بك في دليل
extensions
وتسجيل موقع مصدر الامتداد في ملفfirebase.json
. يُطلق على هذين السجلين معًا اسم بيان الامتدادات . يمكن للمستخدمين استخدام البيان لحفظ تكوينات الامتدادات الخاصة بهم ونشرها في مشاريع مختلفة.انشر تكوين الامتداد الخاص بك إلى مشروعك المباشر:
firebase deploy --only extensions
إذا سارت الأمور على ما يرام، فيجب على واجهة سطر أوامر Firebase تحميل الامتداد إلى مشروعك وتثبيته. بعد اكتمال التثبيت، سيتم تشغيل مهمة إعادة التعبئة، وفي غضون دقائق قليلة، سيتم تحديث قاعدة البيانات الخاصة بك برسائل كبيرة. أضف بعض العقد الجديدة إلى قاعدة بيانات الرسائل وتأكد من أن الامتداد يعمل أيضًا مع الرسائل الجديدة.
- يمكن للمستخدمين إنشاء بيان ملحق باستخدام أمر
firebase ext:install
. يمكنك أيضًا استخدام هذا الأمر لتثبيت ملحق من مصدر محلي. - انشر تكوين ملحق من بيان إلى مشروع مباشر باستخدام
firebase deploy
. - على الرغم من عدم توضيح ذلك هنا، يمكن للمستخدمين أيضًا تثبيت الملحقات في مشاريعهم من Extensions Hub.
معلومات اكثر
راجع وثائق المستخدم حول إدارة تكوينات المشروع باستخدام بيان الإضافات .
10. كتابة الوثائق
قبل مشاركة ملحقك مع المستخدمين، تأكد من توفير الوثائق الكافية لهم لتحقيق النجاح.
عند تهيئة مشروع الامتداد، قامت واجهة سطر أوامر Firebase بإنشاء إصدارات أساسية من الحد الأدنى من الوثائق المطلوبة. قم بتحديث هذه الملفات لتعكس الامتداد الذي قمت بإنشائه بدقة.
Extension.yaml
لقد قمت بالفعل بتحديث هذا الملف أثناء قيامك بتطوير هذا الملحق، لذا لا تحتاج إلى إجراء أي تحديثات أخرى الآن.
ومع ذلك، لا تغفل أهمية الوثائق الموجودة في هذا الملف. بالإضافة إلى المعلومات التعريفية الهامة للامتداد - الاسم والوصف والمؤلف وموقع المستودع الرسمي - يحتوي ملف extension.yaml
على وثائق واجهة المستخدم لكل مورد ومعلمة قابلة للتكوين بواسطة المستخدم. يتم عرض هذه المعلومات للمستخدمين في وحدة تحكم Firebase، وExtensions Hub، وFirebase CLI.
التثبيت المسبق.md
في هذا الملف، قم بتوفير المعلومات التي يحتاجها المستخدم قبل تثبيت الملحق الخاص بك: قم بوصف موجز لما يفعله الملحق، واشرح أي متطلبات أساسية، وقدم للمستخدم معلومات حول الآثار المترتبة على الفوترة لتثبيت الملحق. إذا كان لديك موقع ويب يحتوي على معلومات إضافية، فهذا أيضًا مكان جيد لربطه.
يتم عرض نص هذا الملف للمستخدم في Extensions Hub وبواسطة أمر firebase ext:info
.
فيما يلي مثال لملف التثبيت المسبق:
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.
التغيير.md
يجب عليك أيضًا توثيق التغييرات التي تجريها بين إصدارات الامتداد في الملف CHANGELOG.md
.
نظرًا لأن ملحق المثال لم يتم نشره من قبل، فإن سجل التغيير يحتوي على إدخال واحد فقط:
## Version 0.0.1
Initial release of the _Convert messages to upper case_ extension.
التمهيدي.md
توفر معظم الإضافات أيضًا ملفًا تمهيديًا لصالح المستخدمين الذين يزورون مستودع الإضافات. يمكنك كتابة هذا الملف يدويًا أو إنشاء قراءة لي باستخدام الأمر.
ولأغراض هذا الدليل، تخطى كتابة ملف تمهيدي.
وثائق اضافية
الوثائق التي تمت مناقشتها أعلاه هي الحد الأدنى من الوثائق التي يجب عليك تقديمها للمستخدمين. تتطلب العديد من الإضافات وثائق أكثر تفصيلاً حتى يتمكن المستخدمون من استخدامها بنجاح. في هذه الحالة، يجب عليك كتابة وثائق إضافية واستضافتها في مكان يمكنك توجيه المستخدمين إليه.
ولأغراض هذا الدليل، تخطى كتابة وثائق أكثر شمولاً.
- كحد أدنى، يجب أن يوفر كل ملحق وثائق المستخدم في الملفات التالية:
extension.yaml
.yaml وPREINSTALL.md
وPOSTINSTALL.md
وCHANGELOG.md
. - يجب عليك أيضًا تزويد المستخدمين بوثائق أكثر تفصيلاً عند الضرورة.
معلومات اكثر
راجع التوثيق الخاص بكتابة التوثيق .
11. انشر على مركز الامتدادات
الآن بعد أن اكتمل كود الامتداد الخاص بك وتم توثيقه، أصبحت جاهزًا لمشاركته مع العالم على Extensions Hub. ولكن بما أن هذا مجرد برنامج تعليمي، فلا تفعل ذلك فعليًا. اذهب وابدأ في كتابة الامتداد الخاص بك باستخدام ما تعلمته هنا وفي بقية وثائق ناشري Firebase Extensions، ومن خلال فحص مصدر الامتدادات الرسمية المكتوبة بواسطة Firebase.
عندما تكون مستعدًا لنشر عملك على Extensions Hub، فإليك كيفية القيام بذلك:
- إذا كنت تنشر ملحقك الأول، فقم بالتسجيل كناشر ملحق . عندما تقوم بالتسجيل كناشر ملحقات، فإنك تقوم بإنشاء معرف ناشر يتيح للمستخدمين التعرف عليك بسرعة باعتبارك مؤلف ملحقاتك.
قم باستضافة الكود المصدري لامتدادك في مكان يمكن التحقق منه بشكل عام. عندما يكون الكود الخاص بك متاحًا من مصدر يمكن التحقق منه، يمكن لـ Firebase نشر امتدادك مباشرة من هذا الموقع. يساعد القيام بذلك على ضمان نشر الإصدار الذي تم إصداره حاليًا من ملحقك، ويساعد المستخدمين من خلال السماح لهم بفحص الكود الذي يقومون بتثبيته في مشاريعهم.
ويعني هذا حاليًا إتاحة الامتداد الخاص بك في مستودع GitHub العام.
قم بتحميل الامتداد الخاص بك إلى Extensions Hub باستخدام أمر
firebase ext:dev:upload
.انتقل إلى لوحة تحكم الناشر في وحدة تحكم Firebase، وابحث عن الامتداد الذي قمت بتحميله للتو، وانقر على "نشر إلى Extensions Hub". يتطلب هذا إجراء مراجعة من فريق المراجعة لدينا، الأمر الذي قد يستغرق بضعة أيام. في حالة الموافقة، سيتم نشر الامتداد على Extensions Hub. في حالة الرفض، ستصلك رسالة توضح السبب؛ يمكنك بعد ذلك معالجة المشكلات التي تم الإبلاغ عنها وإعادة إرسالها للمراجعة.
- لمشاركة الملحقات على Extensions Hub، يجب أن تكون مسجلاً كناشر.
- يعد النشر من مصدر يمكن التحقق منه أمرًا مطلوبًا، وهو يمنح المستخدمين ضمانًا بأن الكود الذي يقومون بتثبيته هو نفس الكود الذي يمكنهم فحصه على GitHub.
- استخدم أمر
firebase ext:dev:upload
لتحميل ملحق إلى Extensions Hub. - أرسل ملحقاتك للمراجعة من لوحة تحكم الناشر.
معلومات اكثر
تعرف على المزيد حول التسجيل كناشر ونشر ملحق .