Uzantı oluşturmaya başlayın

Bu sayfa, projelerinize yükleyebileceğiniz veya başkalarıyla paylaşabileceğiniz basit bir Firebase Uzantısı oluşturmak için gereken adımlarda size yol gösterir. Bu basit Firebase Uzantısı örneği, Gerçek Zamanlı Veritabanınızdaki mesajları izleyecek ve bunları büyük harfe dönüştürecektir.

1. Ortamınızı kurun ve bir proje başlatın

Uzantı oluşturmaya başlamadan önce gerekli araçları içeren bir derleme ortamı oluşturmanız gerekir.

  1. Node.js 16 veya daha yenisini yükleyin. Node'u kurmanın bir yolu nvm (veya nvm-windows ) kullanmaktır.

  2. Firebase CLI'nin en son sürümünü yükleyin veya güncelleyin. npm kullanarak yüklemek veya güncellemek için şu komutu çalıştırın:

    npm install -g firebase-tools
    

Şimdi yeni bir uzantı projesi başlatmak için Firebase CLI'yi kullanın:

  1. Uzantınız için bir dizin ve bunun içine bir cd oluşturun:

    mkdir rtdb-uppercase-messages && cd rtdb-uppercase-messages
    
  2. Firebase CLI'nin ext:dev:init komutunu çalıştırın:

    firebase ext:dev:init
    

    İstendiğinde, işlevlerin dili olarak JavaScript'i seçin (ancak kendi uzantınızı geliştirirken TypeScript'i de kullanabileceğinizi unutmayın) ve bağımlılıkları yüklemeniz istendiğinde "evet" yanıtını verin. (Diğer seçenekler için varsayılanları kabul edin.) Bu komut, yeni bir uzantı için, uzantınızı geliştirmeye başlayabileceğiniz bir iskelet kod tabanı oluşturacaktır.

2. Emülatörü kullanarak örnek uzantıyı deneyin

Firebase CLI yeni uzantı dizinini başlattığında, basit bir örnek işlev ve Firebase emülatör paketini kullanarak bir uzantıyı çalıştırmak için gerekli dosyaları içeren bir integration-tests dizini oluşturdu.

Öykünücüde örnek uzantıyı çalıştırmayı deneyin:

  1. integration-tests dizinine geçin:

    cd functions/integration-tests
    
  2. Emülatörü bir demo projesiyle başlatın:

    firebase emulators:start --project=demo-test
    

    Emülatör, uzantıyı önceden tanımlanmış bir "kukla" projeye ( demo-test ) yükler. Şu ana kadarki uzantı, erişildiğinde "merhaba dünya" mesajı döndüren, HTTP ile tetiklenen tek bir işlev olan greetTheWorld oluşuyor.

  3. Emülatör hala çalışıyorken, başlattığınızda yazdırdığı URL'yi ziyaret ederek uzantının greetTheWorld işlevini deneyin.

    Tarayıcınız "Dünyayı selamlamaktan Merhaba Dünya" mesajını görüntüler.

  4. Bu işlevin kaynak kodu, uzantının functions dizinindedir. Kaynağı istediğiniz düzenleyicide veya IDE'de açın:

    işlevler/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. Emülatör çalışırken İşlev kodunuzda yaptığınız değişiklikleri otomatik olarak yeniden yükleyecektir. greetTheWorld işlevinde küçük bir değişiklik yapmayı deneyin:

    işlevler/index.js

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

    Değişikliklerinizi kaydedin. Emülatör kodunuzu yeniden yükleyecektir ve artık işlev URL'sini ziyaret ettiğinizde güncellenmiş karşılama mesajını göreceksiniz.

3. extension.yaml'a temel bilgileri ekleyin

Artık bir geliştirme ortamı kurduğunuza ve uzantı öykünücüsünü çalıştırdığınıza göre, kendi uzantınızı yazmaya başlayabilirsiniz.

Mütevazı bir ilk adım olarak, önceden tanımlanmış uzantı meta verilerini, greet-the-world yerine yazmak istediğiniz uzantıyı yansıtacak şekilde düzenleyin. Bu meta veriler extension.yaml dosyasında saklanır.

  1. Editörünüzde extension.yaml dosyasını açın ve dosyanın tüm içeriğini aşağıdakiyle değiştirin:

    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 alanında kullanılan adlandırma kuralına dikkat edin: Resmi Firebase uzantıları, uzantının çalıştığı birincil Firebase ürününü belirten bir önekle ve ardından uzantının ne yaptığına ilişkin bir açıklamayla adlandırılır. Aynı kuralı kendi uzantılarınızda da kullanmalısınız.

  2. Uzantınızın adını değiştirdiğiniz için emülatör yapılandırmanızı da yeni adla güncellemelisiniz:

    1. functions/integration-tests/firebase.json dosyasında, greet-the-world rtdb-uppercase-messages olarak değiştirin.
    2. functions/integration-tests/extensions/greet-the-world.env functions/integration-tests/extensions/rtdb-uppercase-messages.env olarak yeniden adlandırın.

Uzantı kodunuzda hala greet-the-world uzantısının bazı kalıntıları var, ancak şimdilik bunları bırakın. Sonraki birkaç bölümde bunları güncelleyeceksiniz.

4. Bir Bulut İşlevi yazın ve onu bir uzantı kaynağı olarak bildirin

Artık biraz kod yazmaya başlayabilirsiniz. Bu adımda, uzantınızın temel görevini gerçekleştiren, yani Gerçek Zamanlı Veritabanınızdaki mesajları izlemek ve bunları büyük harfe dönüştürmek olan bir Bulut İşlevi yazacaksınız.

  1. Uzantının işlevlerinin kaynağını (uzantının functions dizininde) düzenleyicide veya seçtiğiniz IDE'de açın. İçeriğini aşağıdakiyle değiştirin:

    işlevler/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);
    });
    

    Değiştirdiğiniz eski işlev, bir HTTP uç noktasına erişildiğinde çalışan, HTTP tarafından tetiklenen bir işlevdi. Yeni işlev, gerçek zamanlı veritabanı olayları tarafından tetiklenir: belirli bir yoldaki yeni öğeleri izler ve bir öğe tespit edildiğinde değerin büyük harfli versiyonunu veritabanına geri yazar.

    Bu arada, bu yeni dosya CommonJS ( require ) yerine ECMAScript modülü sözdizimini ( import ve export ) kullanıyor. Node'da ES modüllerini kullanmak için, functions/package.json dosyasında "type": "module" ifadesini belirtin:

    {
      "name": "rtdb-uppercase-messages",
      "main": "index.js",
      "type": "module",
      …
    }
    
  2. Uzantınızdaki her işlev extension.yaml dosyasında bildirilmelidir. Örnek uzantı, greetTheWorld uzantının tek Bulut İşlevi olarak ilan etti; Artık onu makeuppercase ile değiştirdiğinize göre bildirimini de güncellemeniz gerekiyor.

    extension.yaml açın ve bir resources alanı ekleyin:

    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. Uzantınız artık tetikleyici olarak Gerçek Zamanlı Veritabanını kullandığından, Cloud Functions öykünücüsünün yanında RTDB öykünücüsünü çalıştırmak için öykünücü yapılandırmanızı güncellemeniz gerekir:

    1. Emülatör hala çalışıyorsa Ctrl-C tuşlarına basarak durdurun.

    2. functions/integration-tests dizininden aşağıdaki komutu çalıştırın:

      firebase init emulators
      

      Sorulduğunda, varsayılan projeyi ayarlamayı atlayın ve ardından İşlevler ve Veritabanı öykünücülerini seçin. Varsayılan bağlantı noktalarını kabul edin ve kurulum aracının gerekli dosyaları indirmesine izin verin.

    3. Emülatörü yeniden başlatın:

      firebase emulators:start --project=demo-test
      
  4. Güncellenmiş uzantınızı deneyin:

    1. Öykünücüyü başlattığınızda yazdırılan bağlantıyı kullanarak Veritabanı öykünücüsü kullanıcı arayüzünü açın.

    2. Veritabanının kök düğümünü düzenleyin:

      • Alan: messages
      • Tür: json
      • Değer: {"11": {"original": "recipe"}}

      Her şey doğru ayarlanmışsa, veritabanı değişikliklerinizi kaydettiğinizde, uzantının makeuppercase işlevi tetiklenmeli ve mesaj 11'e "upper": "RECIPE" içeriğini içeren bir alt kayıt eklenmelidir. Beklenen sonuçları doğrulamak için emülatör kullanıcı arayüzünün günlüklerine ve veritabanı sekmelerine göz atın.

    3. messages düğümüne ( {"original":"any text"} ) biraz daha alt öğe eklemeyi deneyin. Yeni bir kayıt eklediğinizde, uzantının original alanın büyük harfli içeriğini içeren bir uppercase alan eklemesi gerekir.

Artık bir RTDB örneğinde çalışan, basit de olsa eksiksiz bir uzantıya sahipsiniz. İlerleyen bölümlerde bu uzantıyı bazı ek özelliklerle geliştireceksiniz. Ardından uzantıyı başkalarına dağıtmaya hazır hale getirecek ve son olarak uzantınızı Extensions Hub'da nasıl yayınlayacağınızı öğreneceksiniz.

5. API'leri ve rolleri bildirin

Firebase, örnek başına bir hizmet hesabı kullanarak, yüklü bir uzantının her örneğine projeye ve verilerine sınırlı erişim sağlar. Her hesabın çalışması için gereken minimum izin seti vardır. Bu nedenle, uzantınızın gerektirdiği tüm IAM rollerini açıkça beyan etmeniz gerekir; kullanıcılar uzantınızı yüklediğinde Firebase, bu rollerin verildiği bir hizmet hesabı oluşturur ve bunu uzantıyı çalıştırmak için kullanır.

Bir ürünün etkinliklerini tetiklemek için roller bildirmeniz gerekmez, ancak ürünle başka şekilde etkileşimde bulunmak için bir rol bildirmeniz gerekir. Son adımda eklediğiniz fonksiyon Realtime Database'e yazdığı için extension.yaml dosyasına aşağıdaki bildirimi eklemeniz gerekir:

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

Benzer şekilde, bir uzantının kullandığı Google API'lerini apis alanında bildirirsiniz. Kullanıcılar uzantınızı yüklediğinde, projeleri için bu API'leri otomatik olarak etkinleştirmek isteyip istemedikleri sorulacaktır. Bu genellikle yalnızca Firebase olmayan Google API'leri için gereklidir ve bu kılavuz için gerekli değildir.

6. Kullanıcı tarafından yapılandırılabilen parametreleri tanımlayın

Son iki adımda oluşturduğunuz işlev, gelen mesajlar için belirli bir RTDB konumunu izledi. Bazen, belirli bir konumu izlemek gerçekten istediğiniz şeydir; örneğin uzantınız, yalnızca uzantınız için kullandığınız bir veritabanı yapısında çalıştığında. Ancak çoğu zaman bu değerleri, projelerine uzantınızı yükleyen kullanıcılar tarafından yapılandırılabilir hale getirmek isteyeceksiniz. Bu şekilde kullanıcılar, mevcut veritabanı kurulumlarıyla çalışmak için uzantınızdan yararlanabilir.

Uzantının yeni mesajlar için izlediği yolu kullanıcı tarafından yapılandırılabilir hale getirin:

  1. extension.yaml dosyasına bir params bölümü ekleyin:

    - 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
    

    Bu, kullanıcılardan uzantınızı yüklediklerinde ayarlamaları istenecek yeni bir dize parametresini tanımlar.

  2. Hala extension.yaml dosyasındayken, makeuppercase bildiriminize geri dönün ve resource alanını aşağıdaki şekilde değiştirin:

    resource: projects/_/instances/${DATABASE_INSTANCE}/refs/${param:MESSAGE_PATH}
    

    ${param:MESSAGE_PATH} jetonu az önce tanımladığınız parametreye bir referanstır. Uzantınız çalıştığında, bu jeton, kullanıcının o parametre için yapılandırdığı değerle değiştirilecektir ve bunun sonucunda, makeuppercase işlevi kullanıcının belirttiği yolu dinleyecektir. Bu sözdizimini, extension.yaml dosyasının (ve POSTINSTALL.md herhangi bir yerinde) herhangi bir kullanıcı tanımlı parametreye başvurmak için kullanabilirsiniz; buna daha sonra değineceğiz.

  3. Kullanıcı tanımlı parametrelere işlev kodunuzdan da erişebilirsiniz.

    Son bölümde yazdığınız fonksiyonda, değişiklikleri izlemek için yolu sabit kodladınız. Bunun yerine tetikleyici tanımını kullanıcı tanımlı değere referans verecek şekilde değiştirin:

    işlevler/index.js

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

    Firebase Uzantıları'nda bu değişikliğin yalnızca belgeleme amaçlı olduğunu unutmayın: Bir Bulut İşlevi bir uzantının parçası olarak dağıtıldığında extension.yaml dosyasındaki tetikleyici tanımını kullanır ve işlev tanımında belirtilen değeri yok sayar. Yine de kodunuzda bu değerin nereden geldiğini belgelemek iyi bir fikirdir.

  4. Çalışma zamanı etkisi olmayan bir kod değişikliği yapmanın hayal kırıklığı yaratabileceğini düşünebilirsiniz, ancak çıkarmanız gereken önemli ders, işlev kodunuzdaki kullanıcı tanımlı herhangi bir parametreye erişebilmeniz ve bunu işlevin mantığında sıradan bir değer olarak kullanabilmenizdir. Bu yeteneğe bir selam olarak, kullanıcının tanımladığı değere gerçekten eriştiğinizi göstermek için aşağıdaki günlük ifadesini ekleyin:

    işlevler/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. Normalde kullanıcılardan bir uzantı yüklediklerinde parametreler için değer sağlamaları istenir. Ancak öykünücüyü test ve geliştirme için kullandığınızda, yükleme işlemini atlarsınız, bunun yerine kullanıcı tanımlı parametreler için değerleri bir env dosyası kullanarak sağlarsınız.

    functions/integration-tests/extensions/rtdb-uppercase-messages.env açın ve GREETING tanımını aşağıdakiyle değiştirin:

    MESSAGE_PATH=/msgs/{pushId}/original
    

    Yukarıdaki yolun varsayılan yoldan ve daha önce tanımladığınız yoldan farklı olduğuna dikkat edin; bu sadece güncellenmiş uzantınızı denediğinizde tanımınızın etkili olduğunu kendinize kanıtlamak içindir.

  6. Şimdi öykünücüyü yeniden başlatın ve veritabanı öykünücüsü kullanıcı arayüzünü bir kez daha ziyaret edin.

    Yukarıda tanımladığınız yolu kullanarak veritabanının kök düğümünü düzenleyin:

    • Alan: msgs
    • Tür: json
    • Değer: {"11": {"original": "recipe"}}

    Veritabanı değişikliklerinizi kaydettiğinizde, uzantının makeuppercase işlevi daha önce olduğu gibi tetiklenmeli, ancak artık kullanıcı tanımlı parametreyi de konsol günlüğüne yazdırmalıdır.

7. Kullanıcı tanımlı mantık için olay kancaları sağlayın

Bir uzantı yazarı olarak, bir Firebase ürününün uzantı tarafından sağlanan mantığınızı nasıl tetikleyebileceğini zaten gördünüz: Gerçek Zamanlı Veritabanında yeni kayıtların oluşturulması, makeuppercase işlevinizi tetikler. Uzantınızın, uzantınızı yükleyen kullanıcılarla benzer bir ilişkisi olabilir: Uzantınız, kullanıcının tanımladığı mantığı tetikleyebilir.

Bir uzantı , eşzamanlı kancalar , eşzamansız kancalar veya her ikisini de sağlayabilir. Eşzamanlı kancalar, kullanıcılara uzantının işlevlerinden birinin tamamlanmasını engelleyen görevleri gerçekleştirmenin bir yolunu sunar. Bu, örneğin kullanıcılara bir uzantı işini yapmadan önce özel ön işleme gerçekleştirmeleri için bir yol sağlamak açısından yararlı olabilir.

Bu kılavuzda, uzantınıza eşzamansız bir kanca ekleyeceksiniz; bu, kullanıcıların, uzantınız büyük harfli mesajı Realtime Database'e yazdıktan sonra çalıştırılacak kendi işlem adımlarını tanımlamalarına olanak tanıyacaktır. Eşzamansız kancalar, kullanıcı tanımlı işlevleri tetiklemek için Eventarc'ı kullanır. Uzantılar, yaydıkları etkinlik türlerini bildirir ve kullanıcılar uzantıyı yüklediğinde hangi etkinlik türleriyle ilgilendiklerini seçerler. En az bir etkinlik seçerlerse Firebase, kurulum sürecinin bir parçası olarak uzantı için bir Eventarc kanalı sağlayacaktır. . Kullanıcılar daha sonra bu kanalı dinleyen ve uzantı yeni etkinlikler yayınladığında tetiklenen kendi bulut işlevlerini dağıtabilirler.

Eşzamansız bir kanca eklemek için şu adımları izleyin:

  1. extension.yaml dosyasına, uzantının yaydığı olay türünü bildiren aşağıdaki bölümü ekleyin:

    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.
    

    Etkinlik türleri evrensel olarak benzersiz olmalıdır; Benzersizliği sağlamak için etkinliklerinizi her zaman şu biçimi kullanarak adlandırın: <publisher-id>.<extension-id>.<version>.<description> . (Henüz bir yayıncı kimliğiniz yok, bu nedenle şimdilik yalnızca test-publisher kullanın.)

  2. makeuppercase fonksiyonunun sonuna, az önce bildirdiğiniz türden bir olayı yayınlayan bir kod ekleyin:

    işlevler/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,
        },
      });
    

    Bu örnek kod, EVENTARC_CHANNEL ortam değişkeninin yalnızca kullanıcı en az bir olay türünü etkinleştirdiğinde tanımlanması gerçeğinden yararlanır. EVENTARC_CHANNEL tanımlı değilse kod herhangi bir olayı yayınlamaya çalışmaz.

    Bir Eventarc olayına ekstra bilgi ekleyebilirsiniz. Yukarıdaki örnekte etkinlik, yeni oluşturulan değere referans içeren bir subject alanına ve orijinal ve büyük harfli mesajları içeren bir data yüküne sahiptir. Olayı tetikleyen kullanıcı tanımlı işlevler bu bilgilerden yararlanabilir.

  3. Normalde EVENTARC_CHANNEL ve EXT_SELECTED_EVENTS ortam değişkenleri, kullanıcının kurulum sırasında seçtiği seçeneklere göre tanımlanır. Emülatörle test yapmak için bu değişkenleri rtdb-uppercase-messages.env dosyasında manuel olarak tanımlayın:

    EVENTARC_CHANNEL=locations/us-central1/channels/firebase
    EXT_SELECTED_EVENTS=test-publisher.rtdb-uppercase-messages.v1.complete
    

Bu noktada, uzantınıza eşzamansız olay kancası eklemek için gereken adımları tamamladınız.

Yeni uyguladığınız bu yeni özelliği denemek için sonraki birkaç adımda uzantıyı yükleyen kullanıcının rolünü üstlenin:

  1. functions/integration-tests dizininden yeni bir Firebase projesi başlatın:

    firebase init functions
    

    İstendiğinde varsayılan proje kurmayı reddedin, Bulut İşlevleri dili olarak JavaScript'i seçin ve gerekli bağımlılıkları yükleyin. Bu proje, uzantınızın yüklü olduğu bir kullanıcının projesini temsil eder.

  2. integration-tests/functions/index.js düzenleyin ve aşağıdaki kodu yapıştırın:

    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}!!!`);
      }
    );
    

    Bu, bir kullanıcının yazabileceği bir işlem sonrası fonksiyonun örneğidir. Bu durumda işlev, complete bir olayı yayınlamak için uzantıyı dinler ve tetiklendiğinde yeni büyük harfli mesaja üç ünlem işareti ekler.

  3. Emülatörü yeniden başlatın. Emülatör, uzantının işlevlerinin yanı sıra "kullanıcının" tanımladığı son işleme işlevini de yükleyecektir.

  4. Veritabanı öykünücüsü kullanıcı arayüzünü ziyaret edin ve yukarıda tanımladığınız yolu kullanarak veritabanının kök düğümünü düzenleyin:

    • Alan: msgs
    • Tür: json
    • Değer: {"11": {"original": "recipe"}}

    Veritabanı değişikliklerinizi kaydettiğinizde, uzantının makeuppercase işlevi ve kullanıcının extraemphasis işlevi sırayla tetiklenmeli ve upper alanın RECIPE!!! .

8. Yaşam döngüsü olay işleyicilerini ekleyin

Şu ana kadar yazdığınız uzantı, mesajları oluşturulduğu anda işler. Peki ya kullanıcılarınız uzantıyı yüklediklerinde zaten bir mesaj veritabanına sahipse? Firebase Uzantıları, uzantınız yüklendiğinde, güncellendiğinde veya yeniden yapılandırıldığında eylemleri tetiklemek için kullanabileceğiniz yaşam döngüsü olay kancaları adı verilen bir özelliğe sahiptir. Bu bölümde, bir kullanıcı uzantınızı yüklediğinde projenin mevcut mesaj veritabanını büyük harfli mesajlarla doldurmak için yaşam döngüsü olay kancalarını kullanacaksınız.

Firebase Extensions, yaşam döngüsü olay işleyicilerinizi çalıştırmak için Cloud Tasks'ı kullanır. Olay işleyicilerini Cloud Functions'ı kullanarak tanımlarsınız; Uzantınızın bir örneği desteklenen yaşam döngüsü olaylarından birine ulaştığında, bir işleyici tanımladıysanız işleyiciyi Bulut Görevleri kuyruğuna ekleyecektir. Cloud Tasks daha sonra işleyiciyi eşzamansız olarak yürütür. Bir yaşam döngüsü olay işleyicisi çalışırken Firebase konsolu, kullanıcıya uzantı örneğinin devam eden bir işleme görevi olduğunu bildirecektir. Devam eden durumu ve görevin tamamlandığını kullanıcıya raporlamak, işleyici işlevinizin sorumluluğundadır.

Mevcut mesajları dolduran bir yaşam döngüsü olay işleyicisi eklemek için aşağıdakileri yapın:

  1. Görev kuyruğu olayları tarafından tetiklenen yeni bir Bulut İşlevi tanımlayın:

    işlevler/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.");
      }
    });
    

    İşlevin, kendisini görev kuyruğuna geri eklemeden önce yalnızca birkaç kaydı işlediğine dikkat edin. Bu, Bulut İşlevinin zaman aşımı penceresi içinde tamamlanamayan işleme görevleriyle başa çıkmak için yaygın olarak kullanılan bir stratejidir. Bir kullanıcının uzantınızı yüklediğinde veritabanında halihazırda kaç mesaj olabileceğini tahmin edemeyeceğiniz için bu strateji çok uygundur.

  2. extension.yaml dosyasında, dolgu işlevinizi, taskQueueTrigger özelliğine sahip bir uzantı kaynağı olarak bildirin:

    resources:
      - name: makeuppercase
        ...
      - name: backfilldata
        type: firebaseextensions.v1beta.function
        description: >-
          Backfill existing messages with uppercase versions
        properties:
          runtime: "nodejs18"
          taskQueueTrigger: {}
    

    Ardından işlevi onInstall yaşam döngüsü olayının işleyicisi olarak bildirin:

    lifecycleEvents:
      onInstall:
        function: backfilldata
        processingMessage: Uppercasing existing messages
    
  3. Mevcut mesajların doldurulması güzel olsa da, uzantı bu olmadan da çalışabilir. Bu gibi durumlarda yaşam döngüsü olay işleyicilerini çalıştırmayı isteğe bağlı hale getirmelisiniz.

    Bunu yapmak için extension.yaml dosyasına yeni bir parametre ekleyin:

    - 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
    

    Daha sonra dolgu fonksiyonunun başlangıcında DO_BACKFILL parametresinin değerini kontrol edin ve ayarlanmamışsa erken çıkın:

    işlevler/index.js

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

Yukarıdaki değişikliklerle birlikte uzantı artık yüklendiğinde mevcut mesajları büyük harfe dönüştürecek.

Bu noktaya kadar uzantınızı geliştirmek ve devam eden değişiklikleri test etmek için uzantı öykünücüsünü kullandınız. Ancak uzantı öykünücüsü yükleme işlemini atlar; dolayısıyla onInstall olay işleyicinizi test etmek için uzantıyı gerçek bir projeye yüklemeniz gerekir. Bu da iyi bir şey çünkü bu otomatik doldurma özelliğinin eklenmesiyle eğitim uzantısı artık kodlarla tamamlandı!

9. Gerçek bir Firebase projesine konuşlandırın

Uzantı öykünücüsü, geliştirme sırasında bir uzantı üzerinde hızlı bir şekilde yineleme yapmak için harika bir araç olsa da, bir noktada onu gerçek bir projede denemek isteyeceksiniz.

Bunu yapmak için önce bazı hizmetlerin etkin olduğu yeni bir proje oluşturun:

  1. Firebase konsolunda yeni bir proje ekleyin.
  2. Projenizi kullandıkça öde Blaze planına yükseltin . Firebase için Cloud Functions, projenizin bir faturalandırma hesabına sahip olmasını gerektirir; dolayısıyla bir uzantı yüklemek için sizin de bir faturalandırma hesabına ihtiyacınız vardır.
  3. Yeni projenizde Gerçek Zamanlı Veritabanını etkinleştirin .
  4. Uzantınızın kurulum sırasında mevcut verileri doldurma yeteneğini test etmek istediğiniz için bazı örnek verileri gerçek zamanlı veritabanı örneğinize aktarın:
    1. Bazı çekirdek RTDB verilerini indirin.
    2. Firebase konsolunun Gerçek Zamanlı Veritabanı sayfasında (more) > JSON'u içe aktar'a tıklayın ve yeni indirdiğiniz dosyayı seçin.
  5. orderByChild yöntemini kullanacak şekilde dolgu işlevini etkinleştirmek için, veritabanını, upper değere göre iletileri dizine ekleyecek şekilde yapılandırın:

    {
      "rules": {
        ".read": false,
        ".write": false,
        "messages": {
          ".indexOn": "upper"
        }
      }
    }
    

Şimdi uzantınızı yerel kaynaktan yeni projeye yükleyin:

  1. Firebase projeniz için yeni bir dizin oluşturun:

    mkdir ~/extensions-live-test && cd ~/extensions-live-test
    
  2. Çalışma dizininde bir Firebase projesi başlatın:

    firebase init database
    

    İstendiğinde yeni oluşturduğunuz projeyi seçin.

  3. Uzantıyı yerel Firebase projenize yükleyin:

    firebase ext:install /path/to/rtdb-uppercase-messages
    

    Burada, Firebase CLI aracını kullanarak bir uzantı yüklerken kullanıcı deneyiminin nasıl olduğunu görebilirsiniz. Yapılandırma aracı mevcut veritabanınızı doldurmak isteyip istemediğinizi sorduğunda "evet"i seçtiğinizden emin olun.

    Yapılandırma seçeneklerini seçtikten sonra Firebase CLI, yapılandırmanızı extensions dizinine kaydedecek ve uzantı kaynağı konumunu firebase.json dosyasına kaydedecektir. Bu iki kayda toplu olarak uzantı bildirimi adı verilir. Kullanıcılar, uzantı yapılandırmalarını kaydetmek ve bunu farklı projelere dağıtmak için bildirimi kullanabilir.

  4. Uzantı yapılandırmanızı canlı projenize dağıtın:

    firebase deploy --only extensions
    

Her şey yolunda giderse Firebase CLI, uzantınızı projenize yüklemeli ve kurmalıdır. Kurulum tamamlandıktan sonra dolgu görevi çalışacak ve birkaç dakika içinde veritabanınız büyük harfli mesajlarla güncellenecektir. Mesaj veritabanına bazı yeni düğümler ekleyin ve uzantının yeni mesajlar için de çalıştığından emin olun.

10. Belgeleri yazın

Uzantınızı kullanıcılarla paylaşmadan önce, başarılı olmaları için yeterli belgeyi sağladığınızdan emin olun.

Uzantı projesini başlattığınızda Firebase CLI, gerekli minimum belgelerin taslak sürümlerini oluşturdu. Oluşturduğunuz uzantıyı doğru şekilde yansıtacak şekilde bu dosyaları güncelleyin.

extension.yaml

Bu uzantıyı geliştirirken bu dosyayı zaten güncelliyorsunuz, dolayısıyla şu anda başka güncelleme yapmanıza gerek yok.

Ancak bu dosyanın içerdiği belgelerin önemini göz ardı etmeyin. Bir uzantının önemli tanımlayıcı bilgilerine (ad, açıklama, yazar, resmi depo konumu) ek olarak extension.yaml dosyası, her kaynak ve kullanıcı tarafından yapılandırılabilir parametreler için kullanıcıya yönelik belgeler içerir. Bu bilgiler Firebase konsolu, Extensions Hub ve Firebase CLI'deki kullanıcılara gösterilir.

PREINSTALL.md

Bu dosyada, kullanıcının uzantınızı yüklemeden önce ihtiyaç duyduğu bilgileri sağlayın: uzantının ne yaptığını kısaca açıklayın, önkoşulları açıklayın ve kullanıcıya, uzantıyı yüklemenin faturalandırma sonuçları hakkında bilgi verin. Ek bilgiler içeren bir web siteniz varsa, burası da bağlantı vermek için iyi bir yerdir.

Bu dosyanın metni kullanıcıya Extensions Hub'da ve firebase ext:info komutuyla görüntülenir.

İşte bir PREINSTALL dosyası örneği:

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

Bu dosya, uzantınızı başarıyla yükledikten sonra kullanıcılar için yararlı bilgiler içerir: örneğin, sonraki kurulum adımları, uzantının kullanım halindeki örneği vb.

POSTINSTALL.md içeriği, bir uzantı yapılandırılıp yüklendikten sonra Firebase konsolunda görüntülenir. Bu dosyadaki kullanıcı parametrelerine başvurabilirsiniz; bunlar, yapılandırılmış değerlerle değiştirilecektir.

Eğitim uzantısı için örnek bir kurulum sonrası dosyası:

### 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

Ayrıca bir uzantının sürümleri arasında yaptığınız değişiklikleri CHANGELOG.md dosyasında belgelemelisiniz.

Örnek uzantı daha önce hiç yayınlanmadığından değişiklik günlüğünde yalnızca bir giriş bulunur:

## Version 0.0.1

Initial release of the _Convert messages to upper case_ extension.

README.md

Çoğu uzantı, uzantının deposunu ziyaret eden kullanıcıların yararına bir benioku dosyası da sağlar. Bu dosyayı elle yazabilir veya komutu kullanarak beni oku oluşturabilirsiniz.

Bu kılavuzun amacı doğrultusunda benioku dosyası yazmayı atlayın.

Ek belgeler

Yukarıda tartışılan belgeler, kullanıcılara sağlamanız gereken minimum belge kümesidir. Pek çok uzantı, kullanıcıların başarılı bir şekilde kullanabilmesi için daha ayrıntılı belgeler gerektirir. Böyle bir durumda ek belgeler yazmalı ve bunları kullanıcıları yönlendirebileceğiniz bir yerde barındırmalısınız.

Bu kılavuzun amacı doğrultusunda, daha kapsamlı belgeler yazmayı atlayın.

11. Extensions Hub'da yayınlayın

Artık uzantınızın kodu tamamlandığına ve belgelendiğine göre, onu Extensions Hub'da dünyayla paylaşmaya hazırsınız. Ancak bu sadece bir eğitim olduğundan, aslında bunu yapmayın. Burada ve Firebase Uzantıları yayıncı belgelerinin geri kalanında öğrendiklerinizi kullanarak ve Firebase tarafından yazılan resmi uzantıların kaynağını inceleyerek kendi uzantınızı yazmaya başlayın.

Çalışmanızı Extensions Hub'da yayınlamaya hazır olduğunuzda bunu şu şekilde gerçekleştireceksiniz:

  1. İlk uzantınızı yayınlıyorsanız, uzantı yayıncısı olarak kaydolun . Uzantı yayıncısı olarak kaydolduğunuzda, kullanıcıların sizi hızlı bir şekilde uzantılarınızın yazarı olarak tanımlamasına olanak tanıyan bir yayıncı kimliği oluşturursunuz.
  2. Uzantınızın kaynak kodunu herkese açık olarak doğrulanabilir bir konumda barındırın. Kodunuz doğrulanabilir bir kaynakta mevcut olduğunda Firebase, uzantınızı doğrudan bu konumdan yayınlayabilir. Bunu yapmak, uzantınızın şu anda yayınlanmış sürümünü yayınladığınızdan emin olmanıza yardımcı olur ve kullanıcıların projelerine yükledikleri kodu incelemelerine olanak tanıyarak yardımcı olur.

    Şu anda bu, uzantınızı herkese açık bir GitHub deposunda kullanılabilir hale getirmek anlamına geliyor.

  3. firebase ext:dev:upload komutunu kullanarak uzantınızı Extensions Hub'a yükleyin.

  4. Firebase konsolunda yayıncı kontrol panelinize gidin, yeni yüklediğiniz uzantıyı bulun ve "Uzantı Merkezinde Yayınla"yı tıklayın. Bu, inceleme ekibimizin birkaç gün sürebilecek bir inceleme yapmasını gerektirir. Onaylanırsa uzantı Extensions Hub'da yayınlanacaktır. Reddedilirse nedenini açıklayan bir mesaj alırsınız; daha sonra bildirilen sorunları çözebilir ve inceleme için yeniden gönderebilirsiniz.