Cloud Functions kodunuzu Firebase Uzantısı olarak yeniden kullanma

1. Başlamadan önce

Firebase uzantıları, HTTP isteklerine yanıt olarak ya da Firebase Cloud Messaging, Cloud Firestore veya Pub/Sub gibi diğer Firebase ve Google ürünlerinden gelen etkinlikleri tetikler.

Oluşturacaklarınız

Bu codelab'de, coğrafi karma oluşturma için bir Firebase uzantısı oluşturacaksınız. Uzantınız dağıtıldıktan sonra X ve Y koordinatlarını, Firestore etkinliklerine yanıt olarak veya çağrılabilir işlev çağrıları yoluyla coğrafi karmalara dönüştürür. Bu, verileri depolamak için tüm hedef platformlarınızda coğrafi yangın kitaplığını uygulamaya alternatif olarak kullanılabilir ve size zaman kazandırır.

Firebase konsolunda gösterilen coğrafi karma uzantısı

Neler öğreneceksiniz?

  • Mevcut Cloud Functions kodunu alıp dağıtılabilir bir Firebase uzantısına dönüştürme
  • extension.yaml dosyası oluşturma
  • Hassas dizeler (API anahtarları) bir uzantıda nasıl depolanır?
  • Uzantı geliştiricilerinin uzantıyı kendi ihtiyaçlarına uygun şekilde yapılandırmasına izin verme
  • Uzantıyı test etme ve dağıtma

Gerekenler

  • Firebase CLI (yükleme ve giriş)
  • Bir Google hesabı (ör. Gmail hesabı)
  • Node.js ve npm
  • En sevdiğiniz geliştirme ortamı

2. Ayarları yapma

Kodu alma

Bu uzantı için ihtiyacınız olan her şeyi bir GitHub deposunda bulabilirsiniz. Başlamak için kodu alın ve favori geliştirme ortamınızda açın.

  1. İndirilen zip dosyasının paketini açın.
  2. Gerekli bağımlılıkları yüklemek için functions dizininde terminali açın ve npm install komutunu çalıştırın.

Firebase'i ayarlayın

Bu codelab, Firebase emülatörlerinin kullanılmasını kesinlikle teşvik eder. Gerçek bir Firebase projesiyle uzantı geliştirmeyi denemek istiyorsanız Firebase projesi oluşturma başlıklı makaleyi inceleyin. Bu codelab'de Cloud Functions kullanılır. Bu nedenle, emülatörler yerine gerçek bir Firebase projesi kullanıyorsanız Blaze fiyatlandırma planına yükseltme yapmanız gerekir.

Bu bölümü atlamak ister misiniz?

Codelab'in tamamlanmış bir sürümünü indirebilirsiniz. Yolda takılırsanız veya tamamlanmış bir uzantının nasıl göründüğünü görmek isterseniz GitHub deposunun codelab-end dalına göz atın veya tamamlanmış ZIP dosyasını indirin.

3. Kodu inceleyin

  • ZIP dosyasındaki index.ts dosyasını açın. Dosyada iki Cloud Functions bildirimi olduğuna dikkat edin.

Bu işlevler ne işe yarar?

Bu demo işlevleri coğrafi karma oluşturma işlemi için kullanılır. Bir koordinat çifti alıp bunları Firestore'daki coğrafi sorgular için optimize edilmiş bir biçime dönüştürürler. İşlevler bir API çağrısı kullanımını simüle eder. Böylece, uzantılardaki hassas veri türlerini yönetme hakkında daha fazla bilgi edinebilirsiniz. Daha fazla bilgi için Firestore'daki verilerde coğrafi sorguları çalıştırma belgelerine bakın.

İşlev sabitleri

Sabitler, en başta, index.ts dosyasının en üstünde bildirilir. Bu sabit değerlerin bazılarına uzantının tanımlanan tetikleyicilerinde referans verilir.

index.ts

import {firestore} from "firebase-functions";
import {initializeApp} from "firebase-admin/app";
import {GeoHashService, ResultStatusCode} from "./fake-geohash-service";
import {onCall} from "firebase-functions/v1/https";
import {fieldValueExists} from "./utils";

const documentPath = "users/{uid}";
const xField = "xv";
const yField = "yv";
const apiKey = "1234567890";
const outputField = "hash";

initializeApp();

const service = new GeoHashService(apiKey);

Firestore Tetikleyicisi

index.ts dosyasındaki ilk işlev şöyle görünür:

index.ts

export const locationUpdate = firestore.document(documentPath)
  .onWrite((change) => {
    // item deleted
    if (change.after == null) {
      return 0;
    }
    // double check that both values exist for computation
    if (
      !fieldValueExists(change.after.data(), xField) ||
      !fieldValueExists(change.after.data(), yField)
    ) {
      return 0;
    }
    const x: number = change.after.data()![xField];
    const y: number = change.after.data()![yField];
    const hash = service.convertToHash(x, y);
    // This is to check whether the hash value has changed. If
    // it hasn't, you don't want to write to the document again as it
    // would create a recursive write loop.
    if (fieldValueExists(change.after.data(), outputField)
      && change.after.data()![outputField] == hash) {
      return 0;
    }
    return change.after.ref
      .update(
        {
          [outputField]: hash.hash,
        }
      );
  });

Bu işlev bir Firestore tetikleyicisidir. Veritabanında bir yazma etkinliği gerçekleştiğinde, işlev bir xv alanı ve yv alanı arayarak bu etkinliğe tepki verir. Ayrıca, bu alanların ikisi de mevcutsa coğrafi karmayı hesaplar ve sonucu, belirtilen bir belge çıkış konumuna yazar. Giriş belgesi, users/{uid} sabitiyle tanımlanır. Diğer bir deyişle, işlev users/ koleksiyonuna yazılan her dokümanı okur ve ardından bu dokümanlar için bir coğrafi karma işler. Daha sonra, karma değerini aynı belgedeki bir karma alanına verir.

Çağrılanabilir İşlevler

index.ts dosyasındaki bir sonraki işlev aşağıdaki gibi görünür:

index.ts

export const callableHash = onCall((data, context) => {
  if (context.auth == undefined) {
    return {error: "Only authorized users are allowed to call this endpoint"};
  }
  const x = data[xField];
  const y = data[yField];
  if (x == undefined || y == undefined) {
    return {error: "Either x or y parameter was not declared"};
  }
  const result = service.convertToHash(x, y);
  if (result.status != ResultStatusCode.ok) {
    return {error: `Something went wrong ${result.message}`};
  }
  return {result: result.hash};
});

onCall işlevine dikkat edin. Bu işlevin, istemci uygulama kodunuzdan çağrılabilecek bir çağrılanabilir işlev olduğunu belirtir. Bu çağrılabilir işlev, x ve y parametrelerini alarak bir coğrafi karma döndürür. Bu işlev, codelab'de doğrudan çağrılmayacak olsa da Firebase uzantısında yapılandırılacak bir örnek olarak buraya eklenmiştir.

4. extensions.yaml dosyası oluşturun

Artık uzantınızdaki Cloud Functions kodunun ne işe yaradığını öğrendiğinize göre onu dağıtım için paketlemeye hazırsınız. Her Firebase Uzantısı, uzantının ne yaptığını ve nasıl davrandığını açıklayan bir extension.yaml dosyası içerir.

extension.yaml dosyası, uzantınızla ilgili bazı başlangıç meta verileri gerektirir. Aşağıdaki adımların her biri, tüm alanların ne anlama geldiğini ve bu alanlara neden ihtiyaç duyduğunuzu anlamanıza yardımcı olur.

  1. Daha önce indirdiğiniz projenin kök dizininde bir extension.yaml dosyası oluşturun. Aşağıdakileri ekleyerek başlayın:
name: geohash-ext
version: 0.0.1
specVersion: v1beta  # Firebase Extensions specification version (do not edit)

Uzantının adı, uzantının örnek kimliğinin temeli olarak kullanılır (kullanıcılar, her biri kendi kimliğine sahip olan bir uzantının birden fazla örneğini yükleyebilir). Ardından Firebase, bu örnek kimliğini kullanarak uzantının hizmet hesaplarının ve uzantıya özel kaynaklarının adını oluşturur. Sürüm numarası, uzantınızın sürümünü belirtir. Anlamsal sürüm oluşturma'ya uygun olması ve uzantının işlevlerinde her değişiklik yaptığınızda bunu güncellemeniz gerekir. Uzantı spesifikasyonu sürümü, hangi Firebase uzantıları spesifikasyonuna uyulacağını belirlemek için kullanılır. Bu örnekte v1beta kullanılır.

  1. YAML dosyasına kullanıcı dostu bazı ayrıntılar ekleyin:
...

displayName: Latitude and longitude to GeoHash converter
description: A converter for changing your Latitude and longitude coordinates to geohashes.

Görünen ad, geliştiriciler uzantınızla etkileşimde bulunurken uzantınızın adının kolay bir şekilde temsil edilir. Açıklama, uzantının işlevine dair kısa bir genel bakış sunar. Uzantı extensions.dev adresine dağıtıldığında şöyle görünür:

extensions.dev adresinde göründüğü şekliyle Geohash Converter uzantısı

  1. Uzantınızdaki kodun lisansını belirtin.
...

license: Apache-2.0  # The license you want for the extension
  1. Uzantıyı kimin yazdığını ve uzantıyı yüklemek için faturalandırma gerekip gerekmediğini belirtin:
...

author:
  authorName: AUTHOR_NAME
  url: https://github.com/Firebase

billingRequired: true

author bölümü, uzantıyla ilgili sorun yaşayan veya uzantı hakkında daha fazla bilgi isteyen kullanıcıların kime ulaşacağını bilmesi için kullanılır. billingRequired zorunlu bir parametredir ve tüm uzantılar Blaze planı gerektiren Cloud Functions işlevlerine bağlı olduğundan true olarak ayarlanmalıdır.

Bu, extension.yaml dosyasında bu uzantıyı tanımlamak için gereken minimum alan sayısını kapsar. Uzantıda belirtebileceğiniz diğer tanımlayıcı bilgiler hakkında daha ayrıntılı bilgi için dokümanlara bakın.

5. Cloud Functions kodunu Extensions kaynağına dönüştürün

Uzantı kaynağı, bir uzantının yüklenmesi sırasında Firebase'in projede oluşturduğu bir öğedir. Böylece uzantı, bu kaynakların sahibi olur ve bunlar üzerinde çalışan belirli bir hizmet hesabına sahip olur. Bu projede bu kaynaklar, Cloud Functions'dır. Uzantı, işlevler klasöründeki koddan otomatik olarak kaynak oluşturmayacağından, extension.yaml dosyasında tanımlanmalıdır. Cloud Functions, kaynak olarak açıkça tanımlanmazsa uzantı dağıtıldığında dağıtılamaz.

Kullanıcı tanımlı dağıtım konumu

  1. Kullanıcının bu uzantıyı dağıtmak istediği konumu belirtmesine izin verin ve uzantıyı son kullanıcılarına daha yakın mı yoksa veritabanına daha yakın mı barındırmanın daha iyi olacağına karar verin. extension.yaml dosyasına konum seçme seçeneği ekleyin.

extension.yaml

Artık işlev kaynağının yapılandırmasını yazmaya hazırsınız.

  1. extension.yaml dosyasında locationUpdate işlevi için bir kaynak nesnesi oluşturun. extension.yaml dosyasına şunu ekleyin:
resources:
  - name: locationUpdate
    type: firebaseextensions.v1beta.function
    properties:
      eventTrigger:
        eventType: providers/cloud.firestore/eventTypes/document.write
        resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}

name öğesini, projenin index.ts dosyasında tanımlanan işlev adı olarak tanımlarsınız. Dağıtılmakta olan işlevin type değerini belirtirsiniz. Şimdilik her zaman firebaseextensions.v1beta.function olmalıdır. Ardından, bu işlevin properties öğesini tanımlarsınız. tanımladığınız ilk özellik, bu işlevle ilişkilendirilmiş eventTrigger öğesidir. Uzantının şu anda desteklediğini yansıtmak için Uzantınız için Cloud Functions işlevlerini yazma belgelerinde bulunan providers/cloud.firestore/eventTypes/document.write eventType öğesini kullanın. resource öğesini, dokümanların konumu olarak tanımlarsınız. Geçerli hedefiniz kodda bulunan içeriği yansıtmak olduğundan belge yolu, önündeki varsayılan veritabanı konumuyla users/{uid} dilini dinler.

  1. Uzantının, Firestore veritabanı için okuma ve yazma izinlerine ihtiyacı vardır. extension.yaml dosyasının en sonunda, geliştiricinin Firebase projesindeki veritabanıyla çalışmak için uzantının erişmesi gereken IAM rollerini belirtin.
roles:
  - role: datastore.user
    reason: Allows the extension to read / write to your Firestore instance.

datastore.user rolü, uzantılar için desteklenen IAM rolleri listesinden gelir. Uzantı okuma ve yazma yapacağından datastore.user rolü buraya uygun.

  1. Çağrılabilir işlev de eklenmelidir. extension.yaml dosyasında, kaynaklar mülkü altında yeni bir kaynak oluşturun. Bu özellikler, çağrılabilir bir işleve özeldir:
  - name: callableHash
    type: firebaseextensions.v1beta.function
    properties:
      httpsTrigger: {}

Önceki kaynak bir eventTrigger kullanmış olsa da burada hem çağrılabilir hem de HTTPS işlevlerini kapsayan bir httpsTrigger kullanıyorsunuz.

Kod kontrolü

Bu, extension.yaml öğenizin index.ts dosyanızdaki kod tarafından yapılan her şeyle eşleşmesi için çok fazla yapılandırma gerektiriyordu. Tamamlanan extension.yaml dosyasının şu anki görünümü aşağıdaki gibi olacaktır:

extension.yaml

name: geohash-ext
version: 0.0.1
specVersion: v1beta  # Firebase Extensions specification version (do not edit)

displayName: Latitude and Longitude to GeoHash converter
description: A converter for changing your Latitude and Longitude coordinates to geohashes.

license: Apache-2.0  # The license you want for the extension

author:
  authorName: Sparky
  url: https://github.com/Firebase

billingRequired: true

resources:
  - name: locationUpdate
    type: firebaseextensions.v1beta.function
    properties:
      eventTrigger:
        eventType: providers/cloud.firestore/eventTypes/document.write
        resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}
  - name: callableHash
    type: firebaseextensions.v1beta.function
    properties:
      httpsTrigger: {}

roles:
  - role: datastore.user
    reason: Allows the extension to read / write to your Firestore instance.

Durum kontrolü

Bu noktada, uzantının başlangıçtaki işlevsel parçaları tamamlanmıştır. Böylece Firebase emülatörlerini kullanarak bu uzantıyı deneyebilirsiniz.

  1. Henüz yapmadıysanız indirilen uzantılar projesinin işlevler klasöründe npm run build çağrısı yapın.
  2. Ana makine sisteminizde yeni bir dizin oluşturun ve firebase init kullanarak bu dizini Firebase projenize bağlayın.
cd ..
mkdir sample-proj
cd sample-proj
firebase init --project=projectID-or-alias
    This command creates a `firebase.json` file in the directory. In the following steps, you push the configuration specified in this file to Firebase.
  1. Aynı dizinde firebase ext:install komutunu çalıştırın. /path/to/extension kısmını, extension.yaml dosyanızı içeren dizinin mutlak yoluyla değiştirin.
firebase ext:install /path/to/extension
    This command does two things:
  • Uzantı örneğinin yapılandırmasını belirtmenizi ister ve örneğin yapılandırma bilgilerini içeren bir *.env dosyası oluşturur.
  • Uzantı örneğini firebase.json öğenizin extensions bölümüne ekler. Bu, örnek kimliğinin uzantı sürümüyle eşleme işlevi görür.
  • Projeyi yerel olarak dağıttığınız için Google Cloud Secret Manager yerine yerel bir dosya kullanmak istediğinizi belirtebilirsiniz.

Bu uzantı yüklenirken gizli anahtarlar için yerel dosyanın kullanıldığını gösteren uzantı yükleme işleminin ekran görüntüsü

  1. Firebase emülatörlerini yeni yapılandırmayla başlatın:
firebase emulators:start
  1. emulators:start çalıştırıldıktan sonra emülatörlerin web görünümündeki Firestore sekmesine gidin.
  2. users koleksiyonuna xv sayı alanı ve yv sayı alanı olan bir doküman ekleyin.

Firebase Emulators'da şu ifadeyi içeren koleksiyon kimliği ile bir koleksiyon başlatmak için gösterilen iletişim kutusu

  1. Uzantıyı başarıyla yüklediyseniz uzantı, dokümanda hash adlı yeni bir alan oluşturur.

xv, yv ve hash alanına sahip bir kullanıcı dokümanı içeren kullanıcı koleksiyonu.

Çakışmaları önlemek için temizleme

  • Testi tamamladıktan sonra uzantıyı kaldırın. Uzantı kodunu güncelleyeceksiniz ve daha sonra mevcut uzantıyla çakışmak istemezsiniz.

Uzantılar, aynı uzantının birden çok sürümünün aynı anda yüklenmesine izin verir. Bu nedenle, uzantıyı kaldırarak daha önce yüklenmiş bir uzantıyla çakışma olmamasını sağlarsınız.

firebase ext:uninstall geohash-ext

Mevcut çözüm işe yarıyor ancak projenin başında belirtildiği gibi, bir hizmetle iletişimi simüle etmek için sabit kodlu bir API anahtarı bulunuyor. Son kullanıcının API anahtarını, orijinal olarak sağlanan anahtar yerine nasıl kullanabilirsiniz? Öğrenmek için okumaya devam edin.

6. Uzantı kullanıcısını yapılandırılabilir hale getirin

Codelab'in bu noktasında, önceden yazdığınız işlevlerin ayrıntılı kurulumuyla kullanılmak üzere yapılandırılmış bir uzantınız var. Peki kullanıcınız kartezyen düzlemde konumu gösteren alanlar için y ve x yerine enlem ve boylam kullanmak isterse ne olur? Ayrıca, son kullanıcının sağlanan API anahtarını kullanmasına izin vermek yerine kendi API anahtarını sağlamasını nasıl sağlayabilirsiniz? Bu API'nin kotasını hızla aşabilirsiniz. Bu durumda, parametreleri ayarlar ve kullanırsınız.

extension.yaml dosyasında temel parametreleri tanımlayın

Geliştiricilerin potansiyel olarak özel yapılandırmaya sahip olabileceği öğeleri dönüştürerek başlayın. İlki, XFIELD ve YFIELD parametreleri olur.

  1. extension.yaml dosyasına, XFIELD ve YFIELD alan parametrelerini kullanan aşağıdaki kodu ekleyin. Bu parametreler, önceden tanımlanmış params YAML mülkünde yer alır:

extension.yaml

params:
  - param: XFIELD
    label: The X Field Name
    description: >-
      The X Field is also known as the **longitude** value. What does
      your Firestore instance refer to as the X value or the longitude
      value. If no value is specified, the extension searches for
      field 'xv'.
    type: string
    validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
    validationErrorMessage: >-
      The field can only contain uppercase or lowercase letter, numbers,
      _, and . characters and must be less than 1500 bytes long. The field
      must also not start with a number.
    default: xv
    required: false
    immutable: false
    example: xv
  - param: YFIELD
    label: The Y Field Name
    description: >-
      The Y Field is also known as the **latitude** value. What does
      your Firestore instance refer to as the Y value or the latitude
      value. If no value is specified, the extension searches for
      field 'yv'.
    type: string
    validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
    validationErrorMessage: >-
      The field can only contain uppercase or lowercase letter, numbers,
      _, and . characters and must be less than 1500 bytes long. The field
      must also not start with a number.
    default: yv
    required: false
    immutable: false
    example: yv
  • param, parametreyi sizin (uzantı üreticisi) görebileceğiniz bir şekilde adlandırır. Bu değeri daha sonra parametre değerlerini belirtirken kullanın.
  • label, parametrenin ne işe yaradığını öğrenmesi için geliştirici tarafından okunabilen bir tanımlayıcıdır.
  • description, değerle ilgili ayrıntılı bir açıklama verir. Bu, Markdown'ı desteklediği için ekstra dokümanlara bağlantı verebilir veya geliştirici için önemli olabilecek kelimeleri vurgulayabilir.
  • type, kullanıcının parametre değerini nasıl ayarlayacağına ilişkin giriş mekanizmasını tanımlar. string, select, multiSelect, selectResource ve secret dahil olmak üzere birçok tür var. Bu seçeneklerin her biri hakkında daha fazla bilgi edinmek için dokümanları inceleyin.
  • validationRegex, geliştirici girişini belirli bir normal ifade değeriyle kısıtlar (örnekte, burada bulunan basit alan adı yönergelerine dayanır); Bu işe yaramazsa...
  • validationErrorMessage, geliştiriciyi hata değeri konusunda uyarır.
  • Geliştirici herhangi bir metin girmediyse default (varsayılan) değeri kullanılır.
  • zorunlu, geliştiricinin herhangi bir metin girmesi gerekmediği anlamına gelir.
  • immutable, geliştiricinin bu uzantıyı güncellemesine ve değeri değiştirmesine olanak tanır. Bu durumda, geliştirici, gereksinimleri değiştikçe alan adlarını değiştirebilir.
  • example, geçerli bir girişin nasıl görünebileceğine dair fikir verir.

Bu konuda çok şey anladım.

  1. Özel bir parametre eklemeden önce extension.yaml dosyasına eklemeniz gereken üç parametre daha var.
  - param: INPUTPATH
    label: The input document to listen to for changes
    description: >-
      This is the document where you write an x and y value to. Once
      that document has received a value, it notifies the extension to
      calculate a geohash and store that in an output document in a certain
      field. This accepts function [wildcard parameters](https://firebase.google.com/docs/functions/firestore-events#wildcards-parameters)
    type: string
    validationRegex: ^[^/]+(/[^/]*/[^/]*)*/[^/]+$
    validationErrorMessage: >-
      This must point to a document path, not a collection path from the root
      of the database. It must also not start or end with a '/' character.
    required: true
    immutable: false
    example: users/{uid}
  - param: OUTPUTFIELD
    label: Geohash field
    description: >-
      This specifies the field in the output document to store the geohash in.
    type: string
    validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
    validationErrorMessage: >-
      The field can only contain uppercase or lowercase letter, numbers,
      _, and . characters and must be less than 1500 bytes long. The field
      must also not start with a number.
    required: false
    default: hash
    immutable: false
    example: hash

Hassas parametreleri tanımlama

Kullanıcının belirttiği API anahtarını yönetmeniz gerekir. Bu, işlevde düz metin olarak depolanmaması gereken hassas bir dizedir. Bunun yerine, bu değeri Cloud gizli anahtar yöneticisinde depolayın. Bu, bulutta şifrelenmiş gizli anahtarları depolayan ve bunların yanlışlıkla sızdırılmasını önleyen özel bir konumdur. Bu işlem, geliştiricinin bu hizmetin kullanımı için ödeme yapmasını gerektirir. Ancak API anahtarları üzerine ekstra bir güvenlik katmanı ekler ve sahtekarlık amaçlı etkinlikleri potansiyel olarak sınırlar. Kullanıcı dokümanları, faturalandırmada sürprizlerin olmaması için geliştiriciyi bunun ücretli bir hizmet olduğu konusunda uyarır. Genel olarak kullanım yukarıda belirtilen diğer dize kaynaklarına benzerdir. Tek fark, secret adlı tür.

  • extension.yaml dosyasına aşağıdaki kodu ekleyin:

extension.yaml

  - param: APIKEY
    label: GeohashService API Key
    description: >-
      Your geohash service API Key. Since this is a demo, and not a real
      service, you can use : 1234567890.
    type: secret
    required: true
    immutable: false

Parametreleri kullanmak için resource özelliklerini güncelleyin.

Daha önce de belirtildiği gibi kaynak (işlev değil), kaynağın nasıl gözlemlendiğini tanımlar. Bu nedenle, yeni parametreyi kullanmak için locationUpdate kaynağının güncellenmesi gerekir.

  • extension.yaml dosyasına aşağıdaki kodu ekleyin:

extension.yaml

## Change from this
  - name: locationUpdate
    type: firebaseextensions.v1beta.function
    properties:
      eventTrigger:
        eventType: providers/cloud.firestore/eventTypes/document.write
        resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}]

## To this
  - name: locationUpdate
    type: firebaseextensions.v1beta.function
    properties:
      eventTrigger:
        eventType: providers/cloud.firestore/eventTypes/document.write
        resource: projects/${PROJECT_ID}/databases/(default)/documents/${INPUTPATH}

extension.yaml dosyasını kontrol edin

  • extension.yaml dosyasını inceleyin. Şuna benzer bir görünümde olacaktır:

extension.yaml

name: geohash-ext
version: 0.0.1
specVersion: v1beta  # Firebase Extensions specification version (do not edit)

displayName: Latitude and Longitude to GeoHash converter
description: A converter for changing your Latitude and Longitude coordinates to geohashes.

license: Apache-2.0  # The license you want to use for the extension

author:
  authorName: Sparky
  url: https://github.com/Firebase

billingRequired: true

params:
  - param: XFIELD
    label: The X Field Name
    description: >-
      The X Field is also known as the **longitude** value. What does
      your Firestore instance refer to as the X value or the longitude
      value. If you don't provide a value for this field, the extension will use 'xv' as the default value.
    type: string
    validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
    validationErrorMessage: >-
      The field can only contain uppercase or lowercase letter, numbers,
      _, and . characters and must be less than 1500 bytes long. The field
      must also not start with a number.
    default: xv
    required: false
    immutable: false
    example: xv
  - param: YFIELD
    label: The Y Field Name
    description: >-
      The Y Field is also known as the **latitude** value. What does
      your Firestore instance refer to as the Y value or the latitude
      Value. If you don't provide a value for this field, the extension will use 'yv' as the default value.
    type: string
    validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
    validationErrorMessage: >-
      The field can only contain uppercase or lowercase letter, numbers,
      _, and . characters and must be less than 1500 bytes long. The field
      must also not start with a number.
    default: yv
    required: false
    immutable: false
    example: yv
  - param: INPUTPATH
    label: The input document to listen to for changes
    description: >-
      This is the document where you write an x and y value to. Once
      that document has been modified, it notifies the extension to
      compute a geohash and store that in an output document in a certain
      field. This accepts function [wildcard parameters](https://firebase.google.com/docs/functions/firestore-events#wildcards-parameters)
    type: string
    validationRegex: ^[^/]+(/[^/]*/[^/]*)*/[^/]+$
    validationErrorMessage: >-
      This must point to a document path, not a collection path from the root
      of the database. It must also not start or end with a '/' character.
    required: true
    immutable: false
    example: users/{uid}
  - param: OUTPUTFIELD
    label: Geohash field
    description: >-
      This specifies the field in the output document to store the geohash in.
    type: string
    validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
    validationErrorMessage: >-
      The field can only contain uppercase or lowercase letter, numbers,
      _, and . characters and must be less than 1500 bytes long. The field
      must also not start with a number.
    required: false
    default: hash
    immutable: false
    example: hash
  - param: APIKEY
    label: GeohashService API Key
    description: >-
      Your geohash service API Key. Since this is a demo, and not a real
      service, you can use : 1234567890.
    type: secret
    required: true
    immutable: false

resources:
  - name: locationUpdate
    type: firebaseextensions.v1beta.function
    properties:
      eventTrigger:
        eventType: providers/cloud.firestore/eventTypes/document.write
        resource: projects/${PROJECT_ID}/databases/(default)/documents/${INPUTPATH}
  - name: callableHash
    type: firebaseextensions.v1beta.function
    properties:
      httpsTrigger: {}

roles:
  - role: datastore.user
    reason: Allows the extension to read / write to your Firestore instance.

Koddaki erişim parametreleri

Tüm parametreleri extension.yaml dosyasında yapılandırdığınıza göre bunları index.ts dosyasına ekleyin.

  • index.ts dosyasında, varsayılan değerleri process.env.PARAMETER_NAME ile değiştirin. Bu işlem, uygun parametre değerlerini getirir ve bu değerleri geliştiricinin Firebase projesinde dağıtılan işlev koduna doldurur.

index.ts

// Replace this:
const documentPath = "users/{uid}";
const xField = "xv";
const yField = "yv";
const apiKey = "1234567890";
const outputField = "hash";

// with this:
const documentPath = process.env.INPUTPATH!; // this value is ignored since its read from the resource
const xField = process.env.XFIELD!;
const yField = process.env.YFIELD!;
const apiKey = process.env.APIKEY!;
const outputField = process.env.OUTPUTFIELD!;

Normalde, ortam değişkeni değerleriyle boş kontroller gerçekleştirmek istersiniz; ancak bu durumda, parametre değerlerinin doğru şekilde kopyalanacağından emin olursunuz. Kod, artık uzantı parametreleriyle çalışacak şekilde yapılandırılmıştır.

7. Kullanıcı dokümanları oluşturma

Kodu emülatörlerde veya Firebase uzantıları pazar yerinde test etmeden önce, geliştiricilerin uzantıyı kullandıklarında ne elde edeceklerini bilmeleri için uzantının belgelenmesi gerekir.

  1. İşlevi, yükleme ön koşullarını ve olası faturalandırma sonuçlarını açıklamak için kullanılan PREINSTALL.md dosyasını oluşturarak başlayın.

PREINSTALL.md

Use this extension to automatically convert documents with a latitude and
longitude to a geohash in your database. Additionally, this extension includes a callable function that allows users to make one-time calls
to convert an x,y coordinate into a geohash.

Geohashing is supported for latitudes between 90 and -90 and longitudes
between 180 and -180.

#### Third Party API Key

This extension uses a fictitious third-party API for calculating the
geohash. You need to supply your own API keys. (Since it's fictitious,
you can use 1234567890 as an API key).

#### Additional setup

Before installing this extension, make sure that you've [set up a Cloud
Firestore database](https://firebase.google.com/docs/firestore/quickstart) in your Firebase project.

After installing this extension, you'll need to:

- Update your client code to point to the callable geohash function if you
want to perform arbitrary geohashes.

Detailed information for these post-installation tasks are provided after
you install this extension.

#### 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:
 - Cloud Firestore
 - Cloud Functions (Node.js 16+ runtime. [See
FAQs](https://firebase.google.com/support/faq#extensions-pricing))
 - [Cloud Secret Manager](https://cloud.google.com/secret-manager/pricing)
  1. Bu proje için README.md öğesini yazarken zamandan tasarruf etmek için kolaylık yöntemini kullanın:
firebase ext:info . --markdown > README.md

Bu işlem, PREINSTALL.md dosyanızın içeriğini ve extension.yaml dosyanızdaki uzantınızla ilgili ek ayrıntıları birleştirir.

Son olarak, uzantının geliştiricisini, yeni yüklenen uzantıya ilişkin bazı ek ayrıntılar hakkında bilgilendirin. Geliştirici, yüklemeyi tamamladıktan sonra bazı ek talimatlar ve bilgiler alabilir ve burada istemci kodunu ayarlama gibi bazı ayrıntılı yükleme sonrası görevler alabilir.

  1. Bir POSTINSTALL.md dosyası oluşturun ve aşağıdaki yükleme sonrası bilgilerini ekleyin:

POSTINSTALL.md

Congratulations on installing the geohash extension!

#### Function information

* **Firestore Trigger** - ${function:locationUpdate.name} was installed
and is invoked when both an x field (${param:XFIELD}) and y field
(${param:YFIELD}) contain a value.

* **Callable Trigger** - ${function:callableHash.name} was installed and
can be invoked by writing the following client code:
 ```javascript
import { getFunctions, httpsCallable } from "firebase/functions";
const functions = getFunctions();
const geoHash = httpsCallable(functions, '${function:callableHash.name}');
geoHash({ ${param:XFIELD}: -122.0840, ${param:YFIELD}: 37.4221 })
  .then((result) => {
    // Read result of the Cloud Function.
    /** @type {any} */
    const data = result.data;
    const error = data.error;
    if (error != null) {
        console.error(`callable error : ${error}`);
    }
    const result = data.result;
    console.log(result);
  });

İzleme

En iyi uygulama olarak, yüklü uzantınızın durumu, kullanımı ve günlükleriyle ilgili denetimler de dahil olmak üzere etkinliğini izleyebilirsiniz.

The output rendering looks something like this when it's deployed:

<img src="img/82b54a5c6ca34b3c.png" alt="A preview of the latitude and longitude geohash converter extension in the firebase console"  width="957.00" />


## Test the extension with the full configuration
Duration: 03:00


It's time to make sure that the user-configurable extension is working the way it is intended.

* Change into the functions folder and ensure that the latest compiled version of the extensions exists. In the extensions project functions directory, call:

```console
npm run build

Böylece işlevleri yeniden derleyerek en son kaynak kodu, uzantı bir emülatöre veya doğrudan Firebase'e dağıtıldığında dağıtımla birlikte dağıtıma hazır olur.

Ardından, uzantıyı test etmek için yeni bir dizin oluşturun. Uzantı mevcut işlevlerden geliştirildiğinden, uzantının yapılandırıldığı klasörden test yapmayın. Bu klasör, işlevleri ve Firebase kurallarını da dağıtmaya çalışır.

Firebase emülatörleriyle yükleme ve test etme

  1. Ana makine sisteminizde yeni bir dizin oluşturun ve firebase init kullanarak bu dizini Firebase projenize bağlayın.
mkdir sample-proj
cd sample-proj
firebase init --project=projectID-or-alias
  1. Uzantıyı yüklemek için bu dizinde firebase ext:install komutunu çalıştırın. /path/to/extension ifadesinin yerine extension.yaml dosyanızı içeren dizinin mutlak yolunu yazın. Bu işlem, uzantınızın yükleme işlemini başlatır ve yapılandırmayı Firebase'e veya emülatörlere aktarmadan önce yapılandırmalarınızı içeren bir .env dosyası oluşturur.
firebase ext:install /path/to/extension
  • Projeyi yerel olarak dağıtacağınız için Google Cloud Secret Manager yerine yerel bir dosya kullanmak istediğinizi belirtin.

da928c65ffa8ce15.png

  1. Yerel emülatör paketini başlatın:
firebase emulators:start

Gerçek bir Firebase projesiyle yükleyip test edin

Uzantınızı gerçek bir Firebase projesine yükleyebilirsiniz. Testiniz için bir test projesi kullanmanız önerilir. Uzantınızın uçtan uca akışını test etmek istiyorsanız veya uzantınızın tetikleyicisi henüz Firebase emülatör paketi tarafından desteklenmiyorsa bu test iş akışını kullanın (Uzantı emülatörü seçeneğine bakın). Emülatörler şu anda Cloud Firestore, Realtime Database ve Pub/Sub için HTTP isteği tarafından tetiklenen işlevleri ve arka plan etkinliği tetiklenen işlevleri desteklemektedir.

  1. Ana makine sisteminizde yeni bir dizin oluşturun ve firebase init kullanarak bu dizini Firebase projenize bağlayın.
cd ..
mkdir sample-proj
cd sample-proj
firebase init --project=projectID-or-alias
  1. Ardından, söz konusu dizinde firebase ext:install komutunu çalıştırarak uzantıyı yükleyin. /path/to/extension ifadesinin yerine extension.yaml dosyanızı içeren dizinin mutlak yolunu yazın. Bu işlem, uzantınızın yükleme işlemini başlatır ve yapılandırmayı Firebase'e veya emülatörlere aktarmadan önce yapılandırmalarınızı içeren bir .env dosyası oluşturur.
firebase ext:install /path/to/extension
  1. Firebase projenize dağıtın.
firebase deploy

Uzantıyı test edin

  1. firebase deploy veya firebase emulators:start çalıştırdıktan sonra, Firebase konsolunun veya emülatörlerin web görünümünün uygun şekilde Firestore sekmesine gidin.
  2. x ve y alanlarında belirtilen koleksiyona bir doküman ekleyin. Bu durumda, güncellenen dokümanlar u/{uid} konumunda, x alanı xv, y alanı ise yv olacak şekilde yer alır.

Firestore kaydı eklemek için Firebase Emulators Ekranı

  1. Uzantıyı başarıyla yüklediyseniz uzantı, iki alanı kaydetmenizin ardından dokümanda hash adlı yeni bir alan oluşturur.

Karmanın eklendiğini gösteren bir emülatörden Firestore veritabanı ekranı

8. Tebrikler!

İlk Cloud Functions işlevinizi başarıyla bir Firebase Uzantısı'na dönüştürdünüz.

Bir extension.yaml dosyası eklediniz ve bu dosyayı, geliştiricilerin uzantınızın nasıl dağıtılmasını istediklerini seçebileceği şekilde yapılandırdınız. Ardından, uzantı geliştiricilerinin uzantıyı kurmadan önce yapmaları gerekenleri ve uzantıyı başarıyla yükledikten sonra atabilecekleri adımlarla ilgili yol gösterici kullanıcı dokümanları oluşturdunuz.

Bir Firebase işlevini dağıtılabilir bir Firebase uzantısına dönüştürmek için gereken temel adımları artık biliyorsunuz.

Sırada ne var?