एक्सटेंशन बनाना शुरू करें

इस पेज पर आपको एक आसान Firebase एक्सटेंशन बनाने के तरीके के बारे में जानकारी दी गई है. इसे अपने प्रोजेक्ट में इंस्टॉल किया जा सकता है या दूसरों के साथ शेयर किया जा सकता है. Firebase एक्सटेंशन का यह आसान उदाहरण, मैसेज के लिए आपके रीयल टाइम डेटाबेस को देखेगा और उन्हें अपर केस में बदल देगा.

1. अपना एनवायरमेंट सेट अप करें और प्रोजेक्ट शुरू करें

एक्सटेंशन बनाना शुरू करने से पहले, आपको ज़रूरी टूल के साथ एक बिल्ड एनवायरमेंट सेट अप करना होगा.

  1. Node.js 16 या इसके बाद का वर्शन इंस्टॉल करें. नोड इंस्टॉल करने का एक तरीका है, nvm (या nvm-Windows) का इस्तेमाल करना.

  2. Firebase सीएलआई का सबसे नया वर्शन इंस्टॉल करें या उसमें अपडेट करें. npm का इस्तेमाल करके इंस्टॉल या अपडेट करने के लिए, इस निर्देश को चलाएं:

    npm install -g firebase-tools
    

अब नया एक्सटेंशन प्रोजेक्ट शुरू करने के लिए, Firebase सीएलआई का इस्तेमाल करें:

  1. अपने एक्सटेंशन के लिए एक डायरेक्ट्री बनाएं और उसमें cd डालें:

    mkdir rtdb-uppercase-messages && cd rtdb-uppercase-messages
    
  2. Firebase सीएलआई का ext:dev:init कमांड चलाएं:

    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) में लोड करता है. अब तक के एक्सटेंशन में, एचटीटीपी से ट्रिगर होने वाला greetTheWorld फ़ंक्शन शामिल है. यह फ़ंक्शन ऐक्सेस करने पर "हैलो वर्ल्ड" मैसेज दिखाता है.

  3. एम्युलेटर के अब भी चल रहे हों, तो एक्सटेंशन के greetTheWorld फ़ंक्शन को आज़माने के लिए, उस यूआरएल पर जाएं जिसे आपने शुरू करते समय प्रिंट किया था.

    आपके ब्राउज़र पर "नमस्ते वर्ल्ड फ़्रॉम ग्रीट-द-वर्ल्ड" का मैसेज दिखता है.

  4. इस फ़ंक्शन का सोर्स कोड, एक्सटेंशन की 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);
    });
    
  5. एम्युलेटर के चलने के दौरान, आपके फ़ंक्शन कोड में किए जाने वाले सभी बदलावों को यह अपने-आप फिर से लोड कर देगा. greetTheWorld फ़ंक्शन में कोई छोटा बदलाव करके देखें:

    फ़ंक्शन/index.js

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

    बदलावों को सेव करें. एम्युलेटर, आपका कोड फिर से लोड करेगा. अब फ़ंक्शन के यूआरएल पर जाने पर, आपको अपडेट किया गया वेलकम मैसेज दिखेगा.

3. extensions.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 Function लिखें और उसे एक्सटेंशन संसाधन के तौर पर एलान करें

अब आप कुछ कोड लिखना शुरू कर सकते हैं. इस चरण में, आपको एक ऐसा क्लाउड फ़ंक्शन लिखना होगा जो आपके एक्सटेंशन का मुख्य टास्क करता है. इसका मकसद, मैसेज के लिए आपके रीयलटाइम डेटाबेस को देखना और उन्हें अपर केस में बदलना है.

  1. एडिटर या अपनी पसंद के 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);
    });
    

    पुराना फ़ंक्शन, जिसे आपने बदला था वह एचटीटीपी से ट्रिगर होने वाला फ़ंक्शन था. यह फ़ंक्शन, एचटीटीपी एंडपॉइंट को ऐक्सेस किए जाने पर चलता था. नया फ़ंक्शन, रीयल-टाइम डेटाबेस इवेंट से ट्रिगर होता है: यह एक खास पाथ पर नए आइटम देखता है. साथ ही, किसी पाथ का पता चलने पर, वैल्यू के अपरकेस वर्शन को डेटाबेस में वापस लिख देता है.

    वैसे, यह नई फ़ाइल CommonJS (require) के बजाय ECMAScript मॉड्यूल सिंटैक्स (import और export) का इस्तेमाल करती है. नोड में ES मॉड्यूल का इस्तेमाल करने के लिए, functions/package.json में "type": "module" तय करें:

    {
      "name": "rtdb-uppercase-messages",
      "main": "index.js",
      "type": "module",
      …
    }
    
  2. आपके एक्सटेंशन के सभी फ़ंक्शन, extension.yaml फ़ाइल में शामिल होने चाहिए. उदाहरण के तौर पर दिए गए एक्सटेंशन में, greetTheWorld को सिर्फ़ Cloud फ़ंक्शन के तौर पर शामिल किया गया है. अब इसे 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. आपका एक्सटेंशन अब रीयल टाइम डेटाबेस का इस्तेमाल ट्रिगर के तौर पर कर रहा है. इसलिए, आपको Cloud Functions एम्युलेटर के साथ-साथ RTDB एम्युलेटर चलाने के लिए अपने एम्युलेटर कॉन्फ़िगरेशन को अपडेट करना होगा:

    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 फ़ंक्शन ट्रिगर हो जाएगा और "upper": "RECIPE" कॉन्टेंट के साथ मैसेज 11 में चाइल्ड रिकॉर्ड जोड़ देगा. उम्मीद के मुताबिक नतीजों की पुष्टि करने के लिए एम्युलेटर यूज़र इंटरफ़ेस (यूआई) के लॉग और डेटाबेस टैब देखें.

    3. messages नोड ({"original":"any text"}) में कुछ और चाइल्ड एंट्री जोड़कर देखें. जब भी कोई नया रिकॉर्ड जोड़ा जाए, तो एक्सटेंशन में original फ़ील्ड के अपरकेस कॉन्टेंट वाला uppercase फ़ील्ड जोड़ना चाहिए.

अब आपके पास पूरा, हालांकि आसान, एक्सटेंशन है जो आरटीडीबी इंस्टेंस पर काम करता है. आने वाले सेक्शन में, आपको इस एक्सटेंशन को कुछ अतिरिक्त सुविधाओं के साथ बेहतर बनाना होगा. इसके बाद, आपका एक्सटेंशन अन्य लोगों को उपलब्ध कराने के लिए तैयार हो जाएगा और अंत में, एक्सटेंशन हब पर अपने एक्सटेंशन को प्रकाशित करने का तरीका जानें.

5. एपीआई और भूमिकाओं की जानकारी देना

Firebase हर इंस्टेंस सेवा खाते का इस्तेमाल करके, इंस्टॉल किए गए एक्सटेंशन के हर इंस्टेंस को प्रोजेक्ट और उसके डेटा का सीमित ऐक्सेस देता है. हर खाते को चलाने के लिए कुछ ज़रूरी अनुमतियां होती हैं. इस वजह से, आपको अपने एक्सटेंशन के लिए ज़रूरी किसी भी IAM रोल के बारे में साफ़ तौर पर बताना होगा. जब उपयोगकर्ता आपका एक्सटेंशन इंस्टॉल करते हैं, तब Firebase इन भूमिकाओं के साथ एक सेवा खाता बनाता है और एक्सटेंशन को चलाने के लिए उसका इस्तेमाल करता है.

किसी प्रॉडक्ट के इवेंट को ट्रिगर करने के लिए, आपको भूमिकाओं की जानकारी देने की ज़रूरत नहीं है. हालांकि, इससे इंटरैक्ट करने के लिए आपको किसी भूमिका का एलान करना होगा. आपने आखिरी चरण में जो फ़ंक्शन जोड़ा था वह रीयलटाइम डेटाबेस को लिखता है. इसलिए, आपको extension.yaml में यह एलान जोड़ना होगा:

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

इसी तरह, आपने उन Google API का एलान किया है जिन्हें कोई एक्सटेंशन, apis फ़ील्ड में इस्तेमाल करता है. जब उपयोगकर्ता आपका एक्सटेंशन इंस्टॉल करेंगे, तो उनसे पूछा जाएगा कि क्या वे अपने प्रोजेक्ट के लिए इन एपीआई को अपने-आप चालू करना चाहते हैं. आम तौर पर, यह सिर्फ़ गैर-Firebase Google API के लिए ज़रूरी है. इस गाइड में इसकी ज़रूरत नहीं है.

6. उपयोगकर्ता द्वारा कॉन्फ़िगर किए जा सकने वाले पैरामीटर परिभाषित करें

पिछले दो चरणों में बनाए गए फ़ंक्शन ने इनकमिंग मैसेज के लिए किसी खास आरटीडीबी लोकेशन को देखा. कभी-कभी, आपकी ज़रूरत के हिसाब से कोई खास जगह देखी जा सकती है. उदाहरण के लिए, जब आपका एक्सटेंशन ऐसी डेटाबेस स्ट्रक्चर पर काम करता है जिसे आपके एक्सटेंशन के लिए खास तौर पर इस्तेमाल किया जाता है. हालांकि, ज़्यादातर मामलों में आप चाहते हैं कि आप इन मानों को उन उपयोगकर्ताओं के लिए कॉन्फ़िगर करना चाहें, जो अपने प्रोजेक्ट में आपका एक्सटेंशन इंस्टॉल करते हैं. इस तरह, उपयोगकर्ता अपने मौजूदा डेटाबेस सेटअप के साथ काम करने के लिए, आपके एक्सटेंशन का इस्तेमाल कर सकते हैं.

नए मैसेज के लिए एक्सटेंशन जिस पाथ को देखता है उसे उपयोगकर्ता के लिए कॉन्फ़िगर करें:

  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. अपने फ़ंक्शन कोड से भी, उपयोगकर्ता के तय किए गए पैरामीटर ऐक्सेस किए जा सकते हैं.

    पिछले सेक्शन में लिखे गए फ़ंक्शन में, आपने बदलावों को देखने के लिए पाथ को हार्ड कोड किया है. इसके बजाय, ट्रिगर की परिभाषा को उपयोगकर्ता की ओर से तय की गई वैल्यू का रेफ़रंस देने के लिए बदलें:

    फ़ंक्शन/index.js

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

    ध्यान दें कि Firebase एक्सटेंशन में, यह बदलाव पूरी तरह से दस्तावेज़ के मकसद से किया गया है: जब Cloud फ़ंक्शन को एक्सटेंशन के हिस्से के तौर पर डिप्लॉय किया जाता है, तो यह extension.yaml फ़ाइल में मौजूद ट्रिगर की परिभाषा का इस्तेमाल करता है और फ़ंक्शन की परिभाषा में बताई गई वैल्यू को अनदेखा कर देता है. फिर भी, यह बेहतर होगा कि आप अपने कोड में यह मान डालने वाले मान को दर्ज करें.

  4. ऐसे कोड में बदलाव करना आपको निराशाजनक लग सकता है जिसका रनटाइम असर नहीं होता है. हालांकि, यह बात याद रखने वाली ज़रूरी बात यह है कि आप अपने फ़ंक्शन कोड में उपयोगकर्ता के तय किए गए किसी भी पैरामीटर को ऐक्सेस कर सकते हैं और इसे फ़ंक्शन के लॉजिक में एक सामान्य वैल्यू के तौर पर इस्तेमाल कर सकते हैं. इस सुविधा के लिए, यहां दिया गया लॉग स्टेटमेंट जोड़ें. इससे पता चलेगा कि आपने उपयोगकर्ता की बताई गई वैल्यू का ही इस्तेमाल किया है:

    फ़ंक्शन/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 कम से कम एक इवेंट चुनता है, तो इंस्टॉल करने की प्रोसेस के हिस्से के तौर पर, 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 फ़ंक्शन के आखिर में, कुछ ऐसा कोड जोड़ें जो आपने अभी-अभी जिस टाइप का इवेंट बताया है उसे पब्लिश करने वाला कोड:

    फ़ंक्शन/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 Functions भाषा के तौर पर चुनें और ज़रूरी डिपेंडेंसी इंस्टॉल करें. यह प्रोजेक्ट, उस उपयोगकर्ता का प्रोजेक्ट दिखाता है जिसमें आपका एक्सटेंशन इंस्टॉल हो चुका है.

  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 एक्सटेंशन, आपके लाइफ़साइकल इवेंट हैंडलर को चलाने के लिए, Cloud Tasks का इस्तेमाल करते हैं. आप Cloud Functions का इस्तेमाल करके इवेंट हैंडलर तय करते हैं; जब भी आपके एक्सटेंशन का कोई इंस्टेंस, इस्तेमाल किए जा सकने वाले लाइफ़साइकल इवेंट में से किसी एक तक पहुंचता है, तो अगर आपने कोई हैंडलर तय किया है, तो यह हैंडलर को Cloud Tasks की सूची में जोड़ देगा. इसके बाद, Cloud Tasks, हैंडलर को एसिंक्रोनस तरीके से एक्ज़ीक्यूट करेगा. जब लाइफ़साइकल इवेंट हैंडलर चल रहा होगा, तब Firebase कंसोल उपयोगकर्ता को रिपोर्ट करेगा कि एक्सटेंशन इंस्टेंस में प्रोसेस करने का काम चल रहा है. उपयोगकर्ता को चल रही स्थिति और काम पूरा होने की जानकारी देना आपके हैंडलर फ़ंक्शन के ऊपर निर्भर करता है.

मौजूदा मैसेज को बैकफ़िल करने वाला लाइफ़साइकल इवेंट हैंडलर जोड़ने के लिए, यह तरीका अपनाएं:

  1. एक नया Cloud फ़ंक्शन तय करें, जो टास्क की सूची के इवेंट से ट्रिगर होता है:

    फ़ंक्शन/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.");
      }
    });
    

    ध्यान दें कि खुद को टास्क सूची में वापस जोड़ने से पहले, यह फ़ंक्शन सिर्फ़ कुछ रिकॉर्ड प्रोसेस करता है. यह आम तौर पर इस्तेमाल की जाने वाली रणनीति है, जो ऐसे टास्क को निपटाने के लिए इस्तेमाल की जाती है जो Cloud फ़ंक्शन की टाइम आउट विंडो में पूरे नहीं हो सकते. आप इसका अनुमान नहीं लगा सकते कि आपका एक्सटेंशन इंस्टॉल करते समय, उपयोगकर्ता के डेटाबेस में पहले से कितने मैसेज मौजूद होंगे, इसलिए यह रणनीति उसके हिसाब से सही है.

  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 पैरामीटर की वैल्यू की जांच करें और अगर यह सेट नहीं है, तो जल्दी बाहर निकलें:

    फ़ंक्शन/index.js

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

ऊपर दिए गए बदलावों के साथ, अब एक्सटेंशन इंस्टॉल होने पर मौजूदा मैसेज को अपरकेस में बदल देगा.

अब तक आपने अपने एक्सटेंशन को डेवलप करने और मौजूदा बदलावों की जांच करने के लिए, एक्सटेंशन एम्युलेटर का इस्तेमाल किया है. हालांकि, एक्सटेंशन एम्युलेटर, इंस्टॉल करने की प्रोसेस को छोड़ देता है. इसलिए, अपने onInstall इवेंट हैंडलर की जांच करने के लिए, आपको किसी असल प्रोजेक्ट में एक्सटेंशन इंस्टॉल करना होगा. हालांकि, इस ऑटोमैटिक बैकफ़िल की सुविधा के शामिल होने के साथ ही, ट्यूटोरियल एक्सटेंशन अब कोड-कंप्लीट हो गया है!

9. किसी असली Firebase प्रोजेक्ट में डिप्लॉय करें

हालांकि, एक्सटेंशन एम्युलेटर, डेवलपमेंट के दौरान एक्सटेंशन पर तेज़ी से काम करने के लिए एक बेहतरीन टूल है, फिर भी आप वाकई इसे किसी असली प्रोजेक्ट में आज़माना चाहेंगे.

ऐसा करने के लिए, पहले एक नया प्रोजेक्ट सेट अप करें, जिसमें कुछ सेवाएं चालू हों:

  1. Firebase कंसोल में, एक नया प्रोजेक्ट जोड़ें.
  2. अपने प्रोजेक्ट को इस्तेमाल के हिसाब से पैसे चुकाएं प्लान पर अपग्रेड करें. 'Firebase के लिए Cloud Functions' को आपके प्रोजेक्ट के लिए एक बिलिंग खाता होना ज़रूरी है. इसलिए, एक्सटेंशन इंस्टॉल करने के लिए आपको बिलिंग खाते की भी ज़रूरत होगी.
  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 सीएलआई टूल का इस्तेमाल करके, एक्सटेंशन इंस्टॉल करते समय उपयोगकर्ता अनुभव कैसा होता है. जब कॉन्फ़िगरेशन टूल पूछे कि क्या आपको अपने मौजूदा डेटाबेस को बैकफ़िल करना है, तो "हां" चुनना न भूलें.

    कॉन्फ़िगरेशन के विकल्प चुनने के बाद, Firebase सीएलआई आपके कॉन्फ़िगरेशन को extensions डायरेक्ट्री में सेव करेगा. साथ ही, एक्सटेंशन के सोर्स की जगह को firebase.json फ़ाइल में रिकॉर्ड करेगा. कुल मिलाकर, इन दो रिकॉर्ड को एक्सटेंशन मेनिफ़ेस्ट कहा जाता है. उपयोगकर्ता अपने एक्सटेंशन कॉन्फ़िगरेशन को सेव करने और उसे अलग-अलग प्रोजेक्ट पर डिप्लॉय करने के लिए, मेनिफ़ेस्ट का इस्तेमाल कर सकते हैं.

  4. अपने लाइव प्रोजेक्ट में एक्सटेंशन कॉन्फ़िगरेशन का इस्तेमाल करें:

    firebase deploy --only extensions
    

अगर सब ठीक रहता है, तो Firebase सीएलआई को आपका एक्सटेंशन आपके प्रोजेक्ट में अपलोड करना चाहिए और उसे इंस्टॉल करना चाहिए. इंस्टॉलेशन पूरा होने के बाद, बैकफ़िल टास्क चलेगा और कुछ ही मिनट में आपके डेटाबेस में अपरकेस मैसेज अपडेट हो जाएंगे. मैसेज के डेटाबेस में कुछ नए नोड जोड़ें और पक्का करें कि एक्सटेंशन नए मैसेज के लिए भी काम कर रहा है.

10. दस्तावेज़ लिखें

उपयोगकर्ताओं के साथ अपने एक्सटेंशन को शेयर करने से पहले, पक्का करें कि उन्हें सफल बनाने के लिए आप ज़रूरी दस्तावेज़ उपलब्ध करा रहे हैं.

जब आपने एक्सटेंशन प्रोजेक्ट शुरू किया, तब Firebase सीएलआई ने ज़रूरी दस्तावेज़ों के स्टब वर्शन बना दिए. इन फ़ाइलों को अपडेट करें, ताकि आपका बनाया गया एक्सटेंशन सही तरीके से दिखे.

एक्सटेंशन.यामल

आपने यह फ़ाइल पहले से ही अपडेट कर दी है क्योंकि आपने यह एक्सटेंशन डेवलप कर लिया है, इसलिए आपको अभी कोई और अपडेट करने की ज़रूरत नहीं है.

हालांकि, इस फ़ाइल में शामिल दस्तावेज़ की अहमियत को नज़रअंदाज़ न करें. एक्सटेंशन की पहचान करने वाली ज़रूरी जानकारी—नाम, ब्यौरा, लेखक, आधिकारिक रिपॉज़िटरी की जगह—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.एमडी

आपको 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 कंसोल में अपने प्रकाशक के डैशबोर्ड पर जाएं, वह एक्सटेंशन ढूंढें जिसे आपने अभी-अभी अपलोड किया है. इसके बाद, "एक्सटेंशन हब पर प्रकाशित करें" पर क्लिक करें. इसके लिए, हमारे समीक्षा स्टाफ़ से समीक्षा करने का अनुरोध किया जाता है. इसमें कुछ दिन लग सकते हैं. अगर एक्सटेंशन को मंज़ूरी मिल जाती है, तो उसे एक्सटेंशन हब में पब्लिश कर दिया जाएगा. अस्वीकार किए जाने पर, आपको एक मैसेज मिलेगा जिसमें आपकी वजह बताई जाएगी. इसके बाद, रिपोर्ट की गई समस्याओं को ठीक करके, उन्हें समीक्षा के लिए फिर से सबमिट किया जा सकता है.