Cloud Functions kodunuzu Firebase Uzantısı olarak yeniden kullanın

1. Başlamadan önce

Firebase Uzantısı, HTTP isteklerine yanıt olarak veya Firebase Cloud Messaging, Cloud Firestore veya Pub/Sub gibi diğer Firebase ve Google ürünlerinden gelen etkinlikleri tetikleyerek belirli bir görevi veya görev kümesini gerçekleştirir.

Ne inşa edeceksin

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, Firestore olaylarına yanıt olarak veya çağrılabilir işlev çağrıları aracılığıyla X ve Y koordinatlarını coğrafi karmalara dönüştürür. Bu, veri depolamak için geofire kitaplığını tüm hedef platformlarınızda uygulamaya alternatif olarak kullanılabilir ve size zaman kazandırır.

Firebase konsolunda gösterilen geohash uzantısı

Ne öğreneceksin

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

İhtiyacınız olan şey

  • Firebase CLI (yükleme ve oturum açma)
  • Gmail hesabı gibi bir Google hesabı
  • Node.js ve npm
  • Favori geliştirme ortamınız

2. Kurulumu yapın

Kodu al

Bu uzantı için ihtiyacınız olan her şey GitHub deposundadır. Başlamak için kodu alın ve favori geliştirme ortamınızda açın.

  1. İndirilen zip dosyasını paketinden çıkarın.
  2. Gerekli bağımlılıkları kurmak için, functions dizininde terminali açın ve npm install komutunu çalıştırın.

Firebase'i kurun

Bu codelab, Firebase öykünücülerinin kullanımını son derece teşvik etmektedir. Uzantı geliştirmeyi gerçek bir Firebase projesiyle denemek istiyorsanız Firebase projesi oluşturma konusuna bakın. Bu codelab, Cloud Functions'ı kullanır; dolayısıyla emülatörler yerine gerçek bir Firebase projesi kullanıyorsanız Blaze fiyatlandırma planına yükseltmeniz gerekir.

İleriye atlamak ister misin?

Codelab'in tamamlanmış bir sürümünü indirebilirsiniz. Yolda takılıp kalırsanız veya tamamlanmış bir uzantının neye benzediğini görmek istiyorsanız GitHub deposunun codelab-end dalına göz atın veya tamamlanmış zip dosyasını indirin.

3. Kodu inceleyin

  • Zip dosyasından index.ts dosyasını açın. İçinde iki Bulut İşlevi bildirimi içerdiğine dikkat edin.

Bu işlevler ne işe yarar?

Bu demo işlevleri coğrafi karma için kullanılır. Bir koordinat çifti alırlar ve bunları Firestore'daki coğrafi sorgular için optimize edilmiş bir formata dönüştürürler. İşlevler, uzantılardaki hassas veri türlerinin işlenmesi hakkında daha fazla bilgi edinebilmeniz için bir API çağrısının kullanımını simüle eder. Daha fazla bilgi için Firestore'daki veriler üzerinde Coğrafi sorgular çalıştırmaya ilişkin belgelere bakın.

Fonksiyon sabitleri

Sabitler, index.ts dosyasının en üstünde önceden bildirilir. Bu sabitlerin bazılarına uzantının tanımlı tetikleyicilerinde başvurulur.

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 Tetikleyici

index.ts dosyasındaki ilk işlev şuna benzer:

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 olayı meydana geldiğinde, işlev bir xv alanı ve bir yv alanı arayarak bu olaya tepki verir ve bu alanların her ikisi de mevcutsa geohash'ı hesaplar ve çıktıyı belirtilen belge çıktı konumuna yazar. Giriş belgesi, users/{uid} sabiti tarafından tanımlanır; bu, işlevin users/ koleksiyona yazılan her belgeyi okuduğu ve ardından bu belgeler için bir geohash işlediği anlamına gelir. Daha sonra hash'i aynı belgedeki hash alanına gönderir.

Çağrılabilir Fonksiyonlar

index.ts dosyasındaki bir sonraki işlev şuna benzer:

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ılabilen, çağrılabilir bir işlev olduğunu belirtir. Bu çağrılabilir işlev, x ve y parametrelerini alır ve bir geohash döndürür. Bu işlev doğrudan bu codelab'de çağrılmayacak olsa da, Firebase uzantısında yapılandırılacak bir şeyin örneği olarak buraya dahil edilmiştir.

4. Bir extension.yaml dosyası oluşturun

Artık uzantınızdaki Bulut İşlevleri kodunun ne yaptığını bildiğ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ıyla birlikte gelir.

Bir 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 bunlara 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 çok örneğini yükleyebilir). Firebase daha sonra bu örnek kimliğini kullanarak uzantının hizmet hesaplarının adını ve uzantıya özgü kaynakları oluşturur. Sürüm numarası, uzantınızın sürümünü gösterir. Anlamsal sürüm belirlemeyi takip etmelidir ve uzantının işlevselliğinde değişiklik yaptığınızda onu güncellemeniz gerekir. Uzantı spesifikasyonu sürümü, hangi Firebase uzantı spesifikasyonunun takip edileceğini belirlemek için kullanılır; bu durumda v1beta kullanılır.

  1. YAML dosyasına bazı kullanıcı dostu 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 bulunduğunda uzantınızın adının kolay anlaşılır bir temsilidir. Açıklama, uzantının ne yaptığına ilişkin kısa bir genel bakış sunar. Uzantı extensions.dev'e dağıtıldığında şuna benzer:

Extensions.dev'de görüldüğü gibi 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 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ü, kullanıcılarınızın uzantıyla ilgili sorun yaşamaları veya uzantı hakkında daha fazla bilgi istemeleri durumunda kime ulaşacaklarını bilmelerini sağlamak için kullanılır. billingRequired gerekli bir parametredir ve tüm uzantılar Blaze planı gerektiren Cloud Functions'a dayandığından true olarak ayarlanması gerekir.

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

5. Bulut İşlevleri kodunu bir Uzantı kaynağına dönüştürün

Uzantı kaynağı, Firebase'in bir uzantının kurulumu sırasında projede oluşturduğu bir öğedir. Uzantı daha sonra bu kaynakların sahibi olur ve bunlar üzerinde çalışan belirli bir hizmet hesabına sahip olur. Bu projede bu kaynaklar, extension.yaml dosyasında tanımlanması gereken Bulut İşlevleridir çünkü uzantı, işlevler klasöründeki koddan otomatik olarak kaynak oluşturacaktır. Bulut İşlevleriniz açıkça bir kaynak olarak bildirilmemişse uzantı dağıtıldığında dağıtılamazlar.

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 mı yoksa veritabanlarına daha yakın mı barındırmanın daha iyi olacağına karar verin. extension.yaml dosyasına konum seçme seçeneğini 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 aşağıdakini 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 projenin index.ts dosyasında tanımlanan işlev adı olarak tanımlarsınız. Şimdilik her zaman firebaseextensions.v1beta.function olması gereken, dağıtılan işlevin type belirtirsiniz. Daha sonra bu fonksiyonun properties tanımlarsınız. tanımladığınız ilk özellik, bu işlevle ilişkilendirilen eventTrigger . Uzantının şu anda desteklediğini yansıtmak için, uzantı belgeleriniz için Yazma Bulut İşlevleri'nde bulunan providers/cloud.firestore/eventTypes/document.write eventType kullanırsınız. resource belgelerin konumu olarak tanımlarsınız. Şu anki hedefiniz kodda var olanı yansıtmak olduğundan, belge yolu, önünde varsayılan veritabanı konumu olacak şekilde users/{uid} dosyasını dinler.

  1. Uzantının Firestore veritabanı için okuma ve yazma izinlerine ihtiyacı var. 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 şeklinde olacağından datastore.user rolü buraya çok uygundur.

  1. Çağrılabilir işlevin de eklenmesi gerekir. extension.yaml dosyasında, Resources özelliği 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 işlevleri hem de HTTPS işlevlerini kapsayan bir httpsTrigger kullanıyorsunuz.

Kod kontrolü

Bu, extension.yaml dosyanızın, index.ts dosyanızdaki kodun yaptığı her şeyle eşleşmesini sağlayacak çok fazla yapılandırmaydı. Tamamlanan extension.yaml dosyasının şu anda böyle görünmesi gerekiyor:

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 ilk işlevsel parçalarını kurdunuz, böylece Firebase emülatörlerini kullanarak gerçekten deneyebilirsiniz!

  1. Henüz yapmadıysanız, indirilen uzantılar projesinin işlevler klasöründe npm run build çağırın.
  2. Ana sisteminizde yeni bir dizin oluşturun ve bu dizini firebase init kullanarak 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ı dizinden firebase ext:install çalıştırın. /path/to/extension yerine extension.yaml dosyanızı içeren dizinin mutlak yolunu yazın.
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 dosyanızın extensions bölümüne ekler. Bu, örnek kimliğinin uzantı sürümüne eşlenmesi görevi 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 yerel dosyanın gizli diziler için kullanıldığını gösteren uzantı yükleme işleminin ekran görüntüsü

  1. Firebase öykünücülerini yeni yapılandırmayla başlatın:
firebase emulators:start
  1. emulators:start çalıştırdıktan sonra, emülatörlerin web görünümündeki Firestore sekmesine gidin.
  2. users koleksiyonuna xv numarası alanı ve yv numarası alanı içeren bir belge ekleyin.

İfadeyi içeren koleksiyon kimliğiyle bir koleksiyon başlatmak için Firebase Emülatörlerinde gösterilen iletişim kutusu

  1. Uzantıyı yüklemede başarılıysanız uzantı, belgede hash adı verilen yeni bir alan oluşturur.

Xv, yv ve hash alanına sahip bir kullanıcı belgesine sahip kullanıcılar koleksiyonu.

Çatışmaları önlemek için temizleyin

  • 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 fazla sürümünün aynı anda yüklenmesine olanak tanır; dolayısıyla, kaldırma işlemiyle, önceden yüklenmiş bir uzantıyla herhangi bir çakışma olmadığından emin olursunuz.

firebase ext:uninstall geohash-ext

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

6. Uzantıyı kullanıcı tarafından yapılandırılabilir hale getirin

Codelab'in bu noktasında, önceden yazdığınız işlevlerin uygun kurulumuyla kullanılmak üzere yapılandırılmış bir uzantınız var, ancak kullanıcınız, alanı belirten alanlar için y ve x yerine enlem ve boylam kullanmak isterse ne olur? kartezyen düzlemde konumu? 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 ayarlayıp kullanırsınız.

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

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

  1. extension.yaml dosyasına XFIELD ve YFIELD alan parametrelerini kullanan aşağıdaki kodu ekleyin. Bu parametreler daha önce tanımlanan params YAML özelliğinin içinde bulunur:

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 uzantı üreticisi olarak sizin görebileceğiniz şekilde adlandırır. Bu değeri daha sonra parametre değerlerini belirlerken kullanın.
  • label , geliştiriciye parametrenin ne yaptığını bildiren, insan tarafından okunabilen bir tanımlayıcıdır.
  • açıklama değerin ayrıntılı bir açıklamasını verir. Bu, işaretlemeyi desteklediğinden, ekstra belgelere bağlantı verebilir veya geliştirici için önemli olabilecek kelimeleri vurgulayabilir.
  • tür, 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 mevcuttur. Bu seçeneklerin her biri hakkında daha fazla bilgi edinmek için belgelere bakın.
  • validationRegex, geliştirici girişini belirli bir normal ifade değeriyle kısıtlar (örnekte , burada bulunan basit alan adı yönergelerine dayanmaktadır); ve eğer bu başarısız olursa...
  • validationErrorMessage geliştiriciyi hata değeri konusunda uyarır.
  • varsayılan , geliştiricinin herhangi bir metin girmemesi durumunda değerin ne olacağıdır.
  • gerekli , geliştiricinin herhangi bir metin girmesine gerek olmadığı anlamına gelir.
  • immutable , geliştiricinin bu uzantıyı güncellemesine ve bu değeri değiştirmesine olanak tanır. Bu durumda geliştiricinin, gereksinimleri değiştikçe alan adlarını değiştirebilmesi gerekir.
  • örnek, geçerli bir girişin nasıl görünebileceğine dair bir fikir sağlar.

Anlaşılması gereken çok şey vardı!

  1. Özel bir parametre eklemeden önce extension.yaml dosyasına eklemeniz gereken üç parametreniz 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ımlayın

Artık kullanıcının belirttiği API anahtarını yönetmeniz gerekiyor. Bu, işlevde düz metin olarak saklanmaması gereken hassas bir dizedir. Bunun yerine, bu değeri Bulut gizli yöneticisinde saklayın. Bu, bulutta şifrelenmiş sırları saklayan ve bunların yanlışlıkla sızdırılmasını önleyen özel bir konumdur. Bu, geliştiricinin bu hizmetin kullanımı için ödeme yapmasını gerektirir, ancak bu, API anahtarları üzerinde ekstra bir güvenlik katmanı ekler ve sahtekarlık faaliyetlerini potansiyel olarak sınırlandırır. Kullanıcı belgeleri, geliştiriciyi bunun ücretli bir hizmet olduğu konusunda uyarır, böylece faturalandırmada herhangi bir sürpriz yaşanmaz. Genel olarak kullanımı yukarıda bahsedilen diğer dize kaynaklarına benzer. Tek fark, secret adı verilen türdü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 niteliklerini güncelleyin

Daha önce de belirtildiği gibi, kaynak (işlev değil) kaynağın nasıl gözlemlendiğini tanımlar, dolayısıyla yeni parametrenin kullanılabilmesi 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. Bunun gibi bir şeye benzemeli:

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 parametrelere erişim

Artık tüm parametreler extension.yaml dosyasında yapılandırıldığına göre bunları index.ts dosyasına ekleyin.

  • index.ts dosyasında, varsayılan değerleri, uygun parametre değerlerini getiren ve bunları geliştiricinin Firebase projesinde dağıtılan işlev koduna yerleştiren process.env.PARAMETER_NAME ile değiştirin.

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ş denetimler gerçekleştirmek istersiniz ancak bu durumda parametre değerlerinin doğru şekilde kopyalandığına güvenirsiniz. Kod artık uzantı parametreleriyle çalışacak şekilde yapılandırılmıştır.

7. Kullanıcı dokümantasyonu oluşturun

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

  1. İşlevselliği, yükleme önkoş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 dosyasını yazarken zaman kazanmak için kolaylık yöntemini kullanın:
firebase ext:info . --markdown > README.md

Bu, 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, yeni yüklenen uzantıyla ilgili bazı ek ayrıntılar hakkında uzantının geliştiricisini bilgilendirin. Geliştirici, kurulumu tamamladıktan sonra bazı ek talimatlar ve bilgiler alabilir ve burada istemci kodunu ayarlamak gibi bazı ayrıntılı kurulum sonrası görevleri alabilir.

  1. Bir POSTINSTALL.md dosyası oluşturun ve ardından aşağıdaki kurulum sonrası bilgileri 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 durumunu, kullanımını ve günlüklerini kontrol etmek 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

Bu, işlevleri yeniden derleyerek en son kaynak kodunun, bir öykünücüye veya doğrudan Firebase'e dağıtıldığında uzantıyla birlikte dağıtıma hazır olmasını sağlar.

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 etmeyin; zira bu, aynı zamanda işlevleri ve Firebase kurallarını da onunla birlikte dağıtmaya çalışır.

Firebase öykünücülerini yükleyin ve test edin

  1. Ana sisteminizde yeni bir dizin oluşturun ve bu dizini firebase init kullanarak 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 dizinden firebase ext:install komutunu çalıştırın. /path/to/extension yerine extension.yaml dosyanızı içeren dizinin mutlak yolunu yazın. Bu, uzantınızın yükleme işlemini başlatır ve yapılandırmayı Firebase'e veya öykünücülere aktarmadan önce yapılandırmalarınızı içeren bir .env dosyası oluşturur.
firebase ext:install /path/to/extension
  • Projeyi yerel olarak dağıttığı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ükleyin ve 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 öykünücü paketi tarafından desteklenmiyorsa bu test iş akışını kullanın ( Uzantı öykünücüsü seçeneğine bakın). Emülatörler şu anda Cloud Firestore, Realtime Database ve Pub/Sub için HTTP isteğiyle tetiklenen işlevleri ve arka plan olayıyla tetiklenen işlevleri desteklemektedir.

  1. Ana sisteminizde yeni bir dizin oluşturun ve bu dizini firebase init kullanarak Firebase projenize bağlayın.
cd ..
mkdir sample-proj
cd sample-proj
firebase init --project=projectID-or-alias
  1. Ardından, uzantıyı yüklemek için bu dizinden firebase ext:install komutunu çalıştırın. /path/to/extension yerine extension.yaml dosyanızı içeren dizinin mutlak yolunu yazın. Bu, uzantınızın yükleme işlemini başlatır ve yapılandırmayı Firebase'e veya öykünücülere 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 komutunu çalıştırdıktan sonra, uygun şekilde Firebase konsolunun Firestore sekmesine veya emülatörlerin web görünümüne gidin.
  2. x alanı ve y alanıyla belirtilen koleksiyona bir belge ekleyin. Bu durumda, güncellenen belgeler x alanı xv ve y alanı yv olacak şekilde u/{uid} konumunda bulunur.

Firestore Kaydı eklemek için Firebase Emülatörleri Ekranı

  1. Uzantıyı yüklemede başarılıysanız, iki alanı kaydettikten sonra uzantı belgede hash adı verilen yeni bir alan oluşturur.

Eklenen hash'i gösteren bir emülatörden Firestore veritabanı ekranı

8. Tebrikler!

İlk Bulut İşlevinizi başarıyla bir Firebase Uzantısına dönüştürdünüz!

Bir extension.yaml dosyası eklediniz ve bunu, geliştiricilerin uzantınızın nasıl dağıtılmasını istediklerini seçebilecekleri şekilde yapılandırdınız. Daha sonra, uzantı geliştiricilerinin uzantıyı kurmadan önce ne yapması gerektiği ve uzantıyı başarıyla yükledikten sonra hangi adımları atması gerekebileceği konusunda rehberlik sağlayan kullanıcı belgeleri oluşturdunuz.

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

Sıradaki ne?