1. Sebelum memulai
Firebase Extensions menjalankan tugas atau serangkaian tugas tertentu sebagai respons terhadap permintaan HTTP atau peristiwa pemicu dari produk Firebase dan Google lainnya seperti Firebase Cloud Messaging, Cloud Firestore, atau Pub/Sub.
Hal yang akan Anda build
Dalam codelab ini, Anda akan mem-build ekstensi Firebase untuk geohashing. Setelah di-deploy, ekstensi Anda akan mengonversi koordinat X dan Y menjadi geohash sebagai respons terhadap peristiwa Firestore atau melalui pemanggilan fungsi yang dapat dipanggil. Hal ini dapat digunakan sebagai alternatif untuk mengimplementasikan library geofire di semua platform target untuk menyimpan data, sehingga menghemat waktu Anda.
Hal yang akan Anda pelajari
- Cara mengambil kode Cloud Functions yang ada dan mengubahnya menjadi Ekstensi Firebase yang dapat didistribusikan
- Cara menyiapkan file
extension.yaml
- Cara menyimpan string sensitif (kunci API) dalam ekstensi
- Cara mengizinkan developer ekstensi mengonfigurasinya agar sesuai dengan kebutuhan mereka
- Cara menguji dan men-deploy ekstensi
Hal yang akan Anda perlukan
- Firebase CLI (penginstalan dan login)
- Akun Google, seperti akun gmail
- Node.js dan
npm
- Lingkungan pengembangan favorit Anda
2. Memulai persiapan
Mendapatkan kode
Semua yang Anda perlukan untuk ekstensi ini ada di repo GitHub. Untuk memulai, ambil kode dan buka di lingkungan pengembangan favorit Anda.
- Mengekstrak file zip yang didownload.
- Untuk menginstal dependensi yang diperlukan, buka terminal di direktori
functions
dan jalankan perintahnpm install
.
Menyiapkan Firebase
Codelab ini sangat mendorong penggunaan emulator Firebase. Jika Anda ingin mencoba pengembangan ekstensi dengan project Firebase sungguhan, lihat membuat project Firebase. Codelab ini menggunakan Cloud Functions, jadi jika Anda menggunakan project Firebase sungguhan, bukan emulator, Anda harus mengupgrade ke paket harga Blaze.
Ingin melewatinya?
Anda dapat mendownload versi lengkap codelab. Jika Anda mengalami kesulitan atau ingin melihat tampilan ekstensi yang sudah selesai, lihat cabang codelab-end
dari repositori GitHub atau download zip yang sudah selesai.
3. Meninjau kode
- Buka file
index.ts
dari file ZIP. Perhatikan bahwa file ini berisi dua deklarasi Cloud Functions di dalamnya.
Apa fungsi dari fungsi ini?
Fungsi demo ini digunakan untuk melakukan geohashing. Mereka mengambil pasangan koordinat dan mengubahnya menjadi format yang dioptimalkan untuk kueri geografis di Firestore. Fungsi ini menyimulasikan penggunaan panggilan API sehingga Anda dapat mempelajari lebih lanjut cara menangani jenis data sensitif di ekstensi. Untuk informasi selengkapnya, lihat dokumentasi tentang menjalankan kueri Geografis pada data di Firestore.
Konstanta fungsi
Konstanta dideklarasikan lebih awal, di bagian atas file index.ts
. Beberapa konstanta ini dirujuk dalam pemicu yang ditentukan ekstensi.
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);
Pemicu Firestore
Fungsi pertama dalam file index.ts
terlihat seperti ini:
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,
}
);
});
Fungsi ini adalah pemicu Firestore. Saat peristiwa tulis terjadi di database, fungsi tersebut akan bereaksi terhadap peristiwa tersebut dengan menelusuri kolom xv
dan kolom yv
. Selain itu, jika kedua kolom tersebut ada, fungsi tersebut akan menghitung geohash dan menulis output ke lokasi output dokumen yang ditentukan. Dokumen input ditentukan oleh konstanta users/{uid}
, yang berarti fungsi tersebut membaca setiap dokumen yang ditulis ke koleksi users/
, lalu memproses geohash untuk dokumen tersebut. Kemudian membuat {i>hash<i} ke sebuah kolom {i>hash<i} dalam dokumen yang sama.
Fungsi yang Dapat Dipanggil
Fungsi berikutnya dalam file index.ts
akan terlihat seperti ini:
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};
});
Perhatikan fungsi onCall
. Hal ini menunjukkan bahwa fungsi ini adalah fungsi yang dapat dipanggil, yang dapat dipanggil dari dalam kode aplikasi klien Anda. Fungsi callable ini menggunakan parameter x
dan y
serta menampilkan geohash. Meskipun tidak akan dipanggil langsung dalam codelab ini, fungsi ini disertakan di sini sebagai contoh sesuatu yang harus dikonfigurasi dalam ekstensi Firebase.
4. Siapkan file ekstensi.yaml
Setelah mengetahui fungsi kode Cloud Functions di ekstensi, Anda siap mengemasnya untuk didistribusikan. Setiap ekstensi Firebase dilengkapi dengan file extension.yaml
yang menjelaskan fungsi ekstensi dan perilakunya.
File extension.yaml
memerlukan beberapa metadata awal tentang ekstensi Anda. Setiap langkah berikut membantu Anda memahami arti semua kolom dan alasan Anda memerlukannya.
- Buat file
extension.yaml
di direktori utama project yang Anda download sebelumnya. Mulailah dengan menambahkan hal-hal berikut:
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
Nama ekstensi digunakan sebagai dasar ID instance ekstensi (pengguna dapat menginstal beberapa instance ekstensi, masing-masing dengan ID-nya sendiri). Firebase kemudian membuat nama akun layanan ekstensi dan resource khusus ekstensi menggunakan ID instance tersebut. Nomor versi menunjukkan versi ekstensi Anda. Versi tersebut harus mengikuti pembuatan versi semantik, dan Anda harus memperbaruinya setiap kali melakukan perubahan pada fungsi ekstensi. Versi spesifikasi ekstensi digunakan untuk menentukan spesifikasi ekstensi Firebase yang akan diikuti, dalam hal ini, v1beta
digunakan.
- Tambahkan beberapa detail yang mudah digunakan ke file YAML:
...
displayName: Latitude and longitude to GeoHash converter
description: A converter for changing your Latitude and longitude coordinates to geohashes.
Nama tampilan adalah representasi praktis dari nama ekstensi Anda saat developer berinteraksi dengan ekstensi Anda. Deskripsi memberikan ringkasan singkat tentang fungsi ekstensi. Saat ekstensi di-deploy di extensions.dev, ekstensi akan terlihat seperti ini:
- Tentukan lisensi untuk kode dalam ekstensi Anda.
...
license: Apache-2.0 # The license you want for the extension
- Tunjukkan siapa yang menulis ekstensi dan apakah ekstensi tersebut memerlukan penagihan atau tidak:
...
author:
authorName: AUTHOR_NAME
url: https://github.com/Firebase
billingRequired: true
Bagian author
digunakan untuk memberi tahu pengguna siapa yang harus dihubungi jika mereka mengalami masalah dengan ekstensi atau ingin mengetahui informasi selengkapnya tentang ekstensi tersebut. billingRequired
adalah parameter wajib dan harus ditetapkan ke true
karena semua ekstensi mengandalkan Cloud Functions, yang memerlukan paket Blaze.
Ini mencakup jumlah minimum kolom yang diperlukan dalam file extension.yaml
untuk mengidentifikasi ekstensi ini. Untuk detail selengkapnya tentang informasi identitas lainnya yang dapat Anda tentukan dalam ekstensi, lihat dokumentasi.
5. Mengonversi kode Cloud Functions menjadi resource Extensions
Resource ekstensi adalah item yang dibuat Firebase dalam project selama penginstalan ekstensi. Ekstensi kemudian memiliki resource tersebut dan memiliki akun layanan tertentu yang beroperasi di resource tersebut. Dalam project ini, resource tersebut adalah Cloud Functions, yang harus ditentukan dalam file extension.yaml
karena ekstensi tidak akan otomatis membuat resource dari kode di folder fungsi. Jika Cloud Functions tidak dideklarasikan secara eksplisit sebagai resource, Cloud Functions tidak dapat di-deploy saat ekstensi di-deploy.
Lokasi deployment yang ditentukan pengguna
- Izinkan pengguna menentukan lokasi tempat mereka ingin men-deploy ekstensi ini dan memutuskan apakah lebih baik menghosting ekstensi lebih dekat ke pengguna akhir atau lebih dekat ke database mereka. Dalam file
extension.yaml
, sertakan opsi untuk memilih lokasi.
extension.yaml
Sekarang Anda siap menulis konfigurasi untuk resource fungsi.
- Di file
extension.yaml
, buat objek resource untuk fungsilocationUpdate
. Tambahkan kode berikut ke fileextension.yaml
:
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}
Anda menentukan name
sebagai nama fungsi yang ditentukan dalam file index.ts
project. Untuk saat ini, Anda menentukan type
fungsi yang di-deploy, yang harus selalu berupa firebaseextensions.v1beta.function
. Kemudian, Anda menentukan properties
fungsi ini. Properti pertama yang Anda tentukan adalah eventTrigger
yang terkait dengan fungsi ini. Untuk mencerminkan apa yang saat ini didukung ekstensi, Anda menggunakan eventType
dari providers/cloud.firestore/eventTypes/document.write
, yang ada dalam dokumentasi Menulis Cloud Functions untuk ekstensi Anda. Anda menentukan resource
sebagai lokasi dokumen. Karena sasaran Anda saat ini adalah mencerminkan apa yang ada dalam kode, jalur dokumen memproses users/{uid}
, dengan lokasi database default di depannya.
- Ekstensi memerlukan izin baca dan tulis untuk database Firestore. Di bagian paling akhir file
extension.yaml
, tentukan peran IAM yang harus dimiliki ekstensi agar dapat menggunakan database di project Firebase developer.
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
Peran datastore.user
berasal dari daftar peran IAM yang didukung untuk ekstensi. Karena ekstensi akan membaca dan menulis, peran datastore.user
sangat cocok di sini.
- Fungsi callable juga harus ditambahkan. Di file
extension.yaml
, buat resource baru di bagian properti resource. Properti ini khusus untuk fungsi yang dapat dipanggil:
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
Meskipun resource sebelumnya menggunakan eventTrigger
, di sini Anda menggunakan httpsTrigger
yang mencakup fungsi callable dan fungsi HTTPS.
Pemeriksaan kode
Ada banyak konfigurasi untuk membuat extension.yaml
cocok dengan semua yang dilakukan oleh kode dalam file index.ts
. Berikut tampilan file extension.yaml
yang sudah selesai saat ini:
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.
Pemeriksaan status
Pada tahap ini, Anda telah menyiapkan bagian fungsional awal dari ekstensi sehingga Anda dapat benar-benar mencobanya menggunakan emulator Firebase.
- Jika Anda belum melakukannya, panggil
npm run build
di folder fungsi dari project ekstensi yang didownload. - Buat direktori baru di sistem host dan hubungkan direktori tersebut ke project Firebase Anda menggunakan
firebase init
.
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.
- Dari direktori yang sama, jalankan
firebase ext:install
. Ganti/path/to/extension
dengan jalur absolut ke direktori yang berisi fileextension.yaml
Anda.
firebase ext:install /path/to/extension
This command does two things:
- Fungsi ini meminta Anda untuk menentukan konfigurasi untuk instance ekstensi, dan akan membuat file
*.env
yang berisi informasi konfigurasi untuk instance tersebut. - Tindakan ini akan menambahkan instance ekstensi ke bagian
extensions
difirebase.json
. Ini berfungsi sebagai peta ID instance ke versi ekstensi. - Karena men-deploy project secara lokal, Anda dapat menentukan apakah ingin menggunakan file lokal, bukan Google Cloud Secret Manager.
- Mulai emulator Firebase dengan konfigurasi baru:
firebase emulators:start
- Setelah menjalankan
emulators:start
, buka tab Firestore di webview emulator. - Tambahkan dokumen ke koleksi
users
dengan kolom angkaxv
dan kolom angkayv
.
- Jika Anda berhasil menginstal ekstensi, ekstensi akan membuat kolom baru bernama
hash
dalam dokumen.
Pembersihan untuk menghindari konflik
- Setelah selesai menguji, uninstal ekstensi—Anda akan memperbarui kode ekstensi dan tidak ingin bertentangan dengan ekstensi saat ini nanti.
Ekstensi memungkinkan beberapa versi ekstensi yang sama diinstal sekaligus, sehingga dengan meng-uninstal, Anda memastikan bahwa tidak ada konflik dengan ekstensi yang diinstal sebelumnya.
firebase ext:uninstall geohash-ext
Solusi saat ini berhasil, tetapi seperti yang disebutkan di awal project, terdapat kunci API hard code untuk menyimulasikan komunikasi dengan layanan. Bagaimana cara menggunakan kunci API pengguna akhir, bukan kunci yang awalnya disediakan? Baca terus untuk mengetahuinya.
6. Membuat pengguna ekstensi dapat dikonfigurasi
Pada tahap codelab ini, Anda memiliki ekstensi yang dikonfigurasi untuk digunakan dengan penyiapan fungsi yang tidak dapat berubah yang telah Anda tulis, tetapi bagaimana jika pengguna ingin menggunakan lintang dan bujur, bukan y dan x, untuk kolom yang menunjukkan lokasi di bidang kartesius? Selain itu, bagaimana cara Anda membuat pengguna akhir memberikan kunci API mereka sendiri, bukan membiarkan mereka menggunakan kunci API yang disediakan? Anda dapat dengan cepat melampaui kuota untuk API tersebut. Dalam hal ini, Anda menyiapkan dan menggunakan parameter.
Menentukan parameter dasar dalam file extension.yaml
Mulai dengan mengonversi item yang mungkin memiliki konfigurasi kustom bagi developer. Yang pertama adalah parameter XFIELD
dan YFIELD
.
- Di file
extension.yaml
, tambahkan kode berikut, yang menggunakan parameter kolomXFIELD
danYFIELD
. Parameter ini berada di dalam properti YAMLparams
yang ditentukan sebelumnya:
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 memberi nama parameter dengan cara yang dapat dilihat oleh Anda, sebagai produsen ekstensi. Gunakan nilai ini nanti saat menentukan nilai parameter.
- label adalah ID yang dapat dibaca manusia bagi developer untuk memberi tahu fungsi parameter.
- description memberikan deskripsi terperinci tentang nilai. Karena mendukung markdown, kode ini dapat ditautkan ke dokumentasi tambahan, atau dapat menandai kata yang mungkin penting bagi developer.
- type menentukan mekanisme input terkait cara pengguna menetapkan nilai parameter. Ada banyak jenis yang ada, termasuk
string
,select
,multiSelect
,selectResource
, dansecret
. Untuk mempelajari setiap opsi ini lebih lanjut, lihat dokumentasi. - validationRegex membatasi entri developer ke nilai ekspresi reguler tertentu (dalam contoh, ini didasarkan pada panduan nama kolom sederhana yang tercantum di sini); dan jika gagal...
- validationErrorMessage memberi tahu developer tentang nilai kegagalan.
- default adalah nilai yang akan digunakan jika developer tidak memasukkan teks apa pun.
- wajib berarti developer tidak diwajibkan memasukkan teks apa pun.
- tidak dapat diubah memungkinkan developer memperbarui ekstensi ini dan mengubah nilai ini. Dalam hal ini, developer harus dapat mengubah nama kolom seiring perubahan persyaratannya.
- example memberikan gambaran tentang tampilan input yang valid.
Sangat banyak yang saya pahami.
- Anda memiliki tiga parameter lagi yang harus ditambahkan ke file
extension.yaml
sebelum menambahkan parameter khusus.
- 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
Menentukan parameter sensitif
Sekarang, Anda perlu mengelola kunci API yang ditentukan pengguna. Ini adalah string sensitif yang tidak boleh disimpan dalam teks biasa dalam fungsi. Simpan nilai ini di Cloud secret manager. Ini adalah lokasi khusus di cloud yang menyimpan secret terenkripsi, dan mencegahnya bocor secara tidak sengaja. Hal ini mengharuskan developer membayar penggunaan layanan ini, tetapi hal ini menambahkan lapisan keamanan ekstra pada kunci API mereka dan berpotensi membatasi aktivitas penipuan. Dokumentasi pengguna memberi tahu developer bahwa layanan ini berbayar, sehingga tidak ada kejutan dalam penagihan. Secara keseluruhan, penggunaannya mirip dengan resource string lain yang disebutkan di atas. Satu-satunya perbedaan adalah jenis yang disebut secret
.
- Di file
extension.yaml
, tambahkan kode berikut:
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
Perbarui atribut resource
untuk menggunakan parameter
Seperti yang disebutkan sebelumnya, resource (bukan fungsi) menentukan cara resource diamati, sehingga resource locationUpdate
perlu diperbarui untuk menggunakan parameter baru.
- Di file
extension.yaml
, tambahkan kode berikut:
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}
Periksa file extension.yaml
- Tinjau file
extension.yaml
. Ini akan terlihat seperti berikut:
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.
Mengakses parameter dalam kode
Setelah semua parameter dikonfigurasi di file extension.yaml
, tambahkan parameter tersebut ke file index.ts
.
- Di file
index.ts
, ganti nilai default denganprocess.env.PARAMETER_NAME
, yang mengambil nilai parameter yang sesuai dan mengisinya dalam kode fungsi yang di-deploy di project Firebase developer.
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!;
Biasanya, Anda ingin melakukan pemeriksaan null dengan nilai variabel lingkungan, tetapi dalam hal ini, Anda yakin bahwa nilai parameter disalin dengan benar. Kode kini dikonfigurasi agar berfungsi dengan parameter ekstensi.
7. Membuat dokumentasi pengguna
Sebelum menguji kode di emulator atau di marketplace ekstensi Firebase, ekstensi perlu didokumentasikan agar developer tahu apa yang mereka dapatkan saat menggunakan ekstensi.
- Mulai dengan membuat file
PREINSTALL.md
, yang digunakan untuk menjelaskan fungsi, prasyarat untuk penginstalan, dan kemungkinan implikasi penagihan.
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)
- Untuk menghemat waktu dalam menulis
README.md
untuk project ini, gunakan metode praktis:
firebase ext:info . --markdown > README.md
File ini menggabungkan konten file PREINSTALL.md
dan detail tambahan tentang ekstensi Anda dari file extension.yaml
.
Terakhir, beri tahu developer ekstensi tersebut tentang beberapa detail tambahan terkait ekstensi yang baru saja diinstal. Developer mungkin mendapatkan beberapa petunjuk dan informasi tambahan setelah menyelesaikan penginstalan dan mungkin mendapatkan beberapa tugas pasca-penginstalan yang mendetail seperti menyiapkan kode klien di sini.
- Buat file
POSTINSTALL.md
, lalu sertakan informasi penginstalan postingan berikut:
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);
});
Pemantauan
Sebagai praktik terbaik, Anda dapat memantau aktivitas ekstensi yang diinstal, termasuk memeriksa respons, penggunaan, dan log-nya.
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
Tindakan ini akan mengompilasi ulang fungsi sehingga kode sumber terbaru siap di-deploy bersama ekstensi saat di-deploy ke emulator atau ke Firebase secara langsung.
Selanjutnya, buat direktori baru untuk menguji ekstensi. Karena ekstensi dikembangkan dari fungsi yang ada, jangan menguji dari folder tempat ekstensi dikonfigurasi karena ekstensi tersebut juga mencoba men-deploy fungsi dan aturan Firebase bersamanya.
Menginstal dan melakukan pengujian dengan emulator Firebase
- Buat direktori baru di sistem host dan hubungkan direktori tersebut ke project Firebase Anda menggunakan
firebase init
.
mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- Dari direktori tersebut, jalankan
firebase ext:install
untuk menginstal ekstensi. Ganti/path/to/extension
dengan jalur absolut ke direktori yang berisi fileextension.yaml
Anda. Tindakan ini akan memulai proses penginstalan ekstensi Anda dan membuat file.env
yang berisi konfigurasi Anda sebelum mengirim konfigurasi ke Firebase atau emulator.
firebase ext:install /path/to/extension
- Karena Anda men-deploy project secara lokal, tentukan bahwa Anda ingin menggunakan file lokal, bukan Google Cloud Secret Manager.
- Mulai suite emulator lokal:
firebase emulators:start
Menginstal dan menguji dengan project Firebase sungguhan
Anda dapat menginstal ekstensi di project Firebase yang sebenarnya. Sebaiknya gunakan project pengujian untuk pengujian. Gunakan alur kerja pengujian ini jika Anda ingin menguji alur menyeluruh ekstensi atau jika pemicu ekstensi Anda belum didukung oleh Firebase emulator suite (lihat Opsi emulator ekstensi). Saat ini emulator mendukung fungsi yang dipicu permintaan HTTP dan fungsi yang dipicu peristiwa latar belakang untuk Cloud Firestore, Realtime Database, dan Pub/Sub.
- Buat direktori baru di sistem host Anda dan hubungkan direktori tersebut ke project Firebase Anda menggunakan
firebase init
.
cd .. mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- Kemudian, dari direktori tersebut, jalankan
firebase ext:install
untuk menginstal ekstensi. Ganti/path/to/extension
dengan jalur absolut ke direktori yang berisi fileextension.yaml
Anda. Tindakan ini akan memulai proses penginstalan untuk ekstensi Anda dan membuat file.env
yang berisi konfigurasi Anda sebelum mendorong konfigurasi ke Firebase atau ke emulator.
firebase ext:install /path/to/extension
- Karena Anda ingin men-deploy ke Firebase secara langsung, dan ingin menggunakan Google Cloud Secret Manager, Anda harus mengaktifkan Secret Manager API sebelum menginstal ekstensi.
- Deploy ke project Firebase Anda.
firebase deploy
Menguji ekstensi
- Setelah menjalankan
firebase deploy
ataufirebase emulators:start
, buka tab Firestore di Firebase console atau webview emulator, yang sesuai. - Tambahkan dokumen ke koleksi yang ditentukan oleh kolom
x
dan kolomy
. Dalam hal ini, dokumen yang diperbarui terletak diu/{uid}
dengan kolomx
xv
dan kolomy
yv
.
- Jika Anda berhasil menginstal ekstensi, ekstensi akan membuat kolom baru bernama
hash
dalam dokumen setelah Anda menyimpan dua kolom.
8. Selamat!
Anda telah berhasil mengonversi Cloud Function pertama menjadi Ekstensi Firebase.
Anda menambahkan file extension.yaml
dan mengonfigurasinya sehingga developer dapat memilih cara deployment ekstensi Anda. Kemudian, Anda membuat dokumentasi pengguna yang memberikan panduan tentang tindakan yang harus dilakukan developer ekstensi sebelum menyiapkan ekstensi dan langkah yang mungkin perlu dilakukan setelah berhasil menginstal ekstensi.
Anda kini sudah mengetahui langkah-langkah utama yang diperlukan untuk mengonversi Firebase Function menjadi Firebase Extensions yang dapat didistribusikan.