Sering kali fungsi Anda memerlukan konfigurasi tambahan, seperti kunci API pihak ketiga atau setelan yang dapat disesuaikan. Firebase SDK untuk Cloud Functions menawarkan konfigurasi lingkungan bawaan untuk memudahkan penyimpanan dan pengambilan jenis data ini untuk project Anda.
Anda dapat memilih di antara tiga opsi:
- Konfigurasi berparameter (direkomendasikan untuk sebagian besar skenario). Opsi ini menyediakan konfigurasi lingkungan strongly-typed dengan parameter yang divalidasi pada waktu deployment, sehingga dapat mencegah error dan menyederhanakan proses debug.
- Konfigurasi berbasis file dari variabel lingkungan. Dengan pendekatan ini, Anda akan membuat file dotenv secara manual untuk memuat variabel lingkungan.
- Konfigurasi lingkungan runtime dengan Firebase CLI
dan
functions.config
(khusus Cloud Functions (generasi ke-1)).
Untuk sebagian besar kasus penggunaan, konfigurasi berparameter direkomendasikan. Dengan pendekatan ini, nilai konfigurasi tersedia baik saat runtime maupun deployment, dan deployment akan diblokir kecuali jika semua parameter memiliki nilai yang valid. Sebaliknya, konfigurasi dengan variabel lingkungan tidak tersedia pada waktu deployment.
Konfigurasi berparameter
Cloud Functions for Firebase menyediakan antarmuka untuk menetapkan parameter konfigurasi secara deklaratif di dalam codebase Anda. Nilai parameter ini tersedia selama deployment fungsi, saat menetapkan opsi deployment dan runtime, serta selama eksekusi. Hal ini berarti bahwa CLI akan memblokir deployment kecuali jika semua parameter memiliki nilai yang valid.
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineInt, defineString } = require('firebase-functions/params');
// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');
// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python (pratinjau)
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
# To use configured parameters inside the config for a function, provide them
# directly. To use them at runtime, call .value() on them.
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')
Saat men-deploy fungsi dengan variabel konfigurasi berparameter, Firebase CLI terlebih dahulu akan mencoba memuat nilai variabel tersebut dari file .env lokal. Jika nilai tersebut tidak ditemukan dan tidak ada default
yang ditetapkan, CLI akan meminta nilai ini selama deployment, lalu otomatis menyimpannya ke file .env
bernama .env.<project_ID>
di direktori functions/
Anda:
$ firebase deploy
i functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i functions: Loaded environment variables from .env.projectId
Bergantung pada alur kerja pengembangan Anda, sebaiknya tambahkan file .env.<project_ID>
yang dihasilkan ke kontrol versi.
Mengonfigurasi perilaku CLI
Parameter dapat dikonfigurasi dengan objek Options
yang mengontrol cara CLI meminta nilai. Contoh berikut menetapkan opsi untuk memvalidasi format nomor telepon, memberikan opsi pemilihan sederhana, dan mengisi opsi pemilihan secara otomatis dari project Firebase:
Node.js
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});
const onlyPhoneNumbers = defineString('PHONE_NUMBER', {input: {text:
{validationRegex: /\d{3}-\d{3}-\d{4}/, validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"}}});
const selectedOption = defineString('PARITY', {input: {select: {options:
[{value: "odd"}, {value: "even"}]}}})
const storageBucket = defineString('BUCKET', {input: {resource: {type:
"storage.googleapis.com/Bucket"}}, description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets"})
Python (pratinjau)
from firebase_functions.params import (
StringParam,
TextInput,
SelectInput,
SelectOptions,
ResourceInput,
)
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam(
"WELCOME_MESSAGE",
default="Hello World",
description="The greeting that is returned to the caller of this function",
)
ONLY_PHONE_NUMBERS = StringParam(
"PHONE_NUMBER",
input=TextInput(
validation_regex="\d{3}-\d{3}-\d{4}",
validation_error_message="Please enter a phone number in the format XXX-YYY-XXX",
),
)
SELECT_OPTION = StringParam(
"PARITY",
input=SelectInput([SelectOptions(value="odd"), SelectOptions(value="even")]),
)
STORAGE_BUCKET = StringParam(
"BUCKET",
input=ResourceInput(type="storage.googleapis.com/Bucket"),
description="This will automatically populate the selector field with the deploying Cloud Project's storage buckets",
)
Jenis-jenis parameter
Konfigurasi berparameter menyediakan strong typing untuk parameter value, dan juga mendukung secret dari Cloud Secret Manager. Jenis yang didukung adalah:
- Secret
- String
- Boolean
- Bilangan bulat
- Float
Nilai dan ekspresi parameter
Firebase mengevaluasi parameter pada waktu deployment dan saat fungsi dieksekusi. Karena adanya lingkungan ganda ini, Anda harus cermat saat membandingkan parameter value, dan saat menggunakannya untuk menetapkan opsi runtime bagi fungsi Anda.
Untuk meneruskan parameter ke fungsi Anda sebagai opsi runtime, teruskan secara langsung:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineInt } = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO\_WORLD\_MININSTANCES');
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python (pratinjau)
from firebase_functions import https_fn
from firebase_functions.params import IntParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
Selain itu, jika Anda perlu membandingkan parameter untuk mengetahui opsi yang sebaiknya dipilih, Anda harus menggunakan komparator bawaan, bukan memeriksa nilai:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const environment = params.defineString(‘ENVIRONMENT’, {default: 'dev'});
// use built-in comparators
const minInstancesConfig = environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python (pratinjau)
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
ENVIRONMENT = StringParam("ENVIRONMENT", default="dev")
MIN_INSTANCES = ENVIRONMENT.equals("PRODUCTION").then(10, 0)
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
Parameter dan ekspresi parameter yang hanya digunakan saat runtime dapat diakses dengan fungsi value
-nya:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');
// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = onRequest(
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python (pratinjau)
from firebase_functions import https_fn
from firebase_functions.params import StringParam
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
@https_fn.on_request()
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')
Parameter bawaan
Cloud Functions SDK menawarkan tiga parameter yang telah ditetapkan, yang tersedia dari sub-paket firebase-functions/params
:
Node.js
projectId
— project Cloud tempat fungsi dijalankan.databaseUrl
— URL instance Realtime Database yang terkait dengan fungsi tersebut (jika diaktifkan di project Firebase).storageBucket
— bucket Cloud Storage yang terkait dengan fungsi tersebut (jika diaktifkan di project Firebase).
Python (pratinjau)
PROJECT_ID
— project Cloud tempat fungsi dijalankan.DATABASE_URL
— URL instance Realtime Database yang terkait dengan fungsi tersebut (jika diaktifkan di project Firebase).STORAGE_BUCKET
— bucket Cloud Storage yang terkait dengan fungsi tersebut (jika diaktifkan di project Firebase).
Dalam semua hal, parameter ini berfungsi seperti parameter string yang ditentukan pengguna. Namun, karena nilainya selalu diketahui oleh Firebase CLI, nilai tersebut tidak akan pernah diminta saat deployment atau disimpan ke file .env
.
Parameter secret
Parameter jenis Secret
, yang ditentukan menggunakan defineSecret()
, mewakili parameter string yang memiliki nilai yang disimpan di Cloud Secret Manager. Alih-alih memeriksa file .env
lokal dan menulis nilai baru ke file ini jika nilai tersebut tidak ada, parameter secret memeriksa keberadaan nilai di Cloud Secret Manager, dan secara interaktif meminta nilai secret baru selama deployment.
Parameter secret yang ditentukan dengan cara ini harus terikat dengan fungsi individual yang harus memiliki akses ke parameter tersebut:
Node.js
const { onRequest } = require("functions/v2/https");
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');
export const postToDiscord = onRequest(
{ secrets: [discordApiKey] },
(req, res) => {
const apiKey = discordApiKey.value();
//…
Python (pratinjau)
from firebase_functions import https_fn
from firebase_functions.params import SecretParam
DISCORD_API_KEY = SecretParam('DISCORD_API_KEY');
@https_fn.on_request(secrets=[DISCORD_API_KEY])
def post_to_discord(req):
api_key = DISCORD_API_KEY.value()
Karena nilai secret ini tersembunyi hingga fungsi dieksekusi, Anda tidak dapat menggunakannya saat mengonfigurasi fungsi.
Variabel lingkungan
Cloud Functions for Firebase mendukung format file
dotenv
untuk memuat variabel lingkungan yang ditentukan dalam .env
file ke
runtime aplikasi Anda. Setelah di-deploy, variabel lingkungan dapat dibaca melalui
process.env
antarmuka.
Untuk mengonfigurasi lingkungan dengan cara ini, buat file .env
di project Anda, tambahkan variabel yang diinginkan, dan deploy:
Buat file
.env
di direktorifunctions/
Anda:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
Buka file
.env
untuk mengedit, lalu tambahkan kunci yang diinginkan. Contoh:PLANET=Earth AUDIENCE=Humans
Deploy fungsi dan pastikan variabel lingkungan telah dimuat:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
Setelah variabel lingkungan kustom di-deploy, kode fungsi Anda dapat mengaksesnya dengan sintaksis process.env
:
Node.js
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
Python (pratinjau)
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
)
Men-deploy beberapa kumpulan variabel lingkungan
Jika Anda memerlukan kumpulan variabel lingkungan alternatif untuk project Firebase (seperti staging vs. produksi), buat file .env.<project or
alias>
dan tulis variabel lingkungan khusus project di sana. Variabel lingkungan dari .env
dan file .env
khusus project (jika ada) akan disertakan dalam semua fungsi yang di-deploy.
Misalnya, project dapat menyertakan tiga file ini yang berisi nilai yang sedikit berbeda untuk pengembangan dan produksi:
.env
|
.env.dev
|
.env.prod
|
PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Prod Humans |
Mengingat nilai dalam file terpisah tersebut, kumpulan variabel lingkungan yang di-deploy dengan fungsi Anda akan bervariasi, bergantung pada project target:
$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
# PLANET=Earth
# AUDIENCE=Dev Humans
$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
# PLANET=Earth
# AUDIENCE=Prod Humans
Variabel lingkungan yang dicadangkan
Beberapa kunci variabel lingkungan dicadangkan untuk penggunaan internal. Jangan gunakan kunci berikut dalam file .env
Anda:
- Semua kunci yang dimulai dengan X_GOOGLE_
- Semua kunci yang dimulai dengan EXT_
- Semua kunci yang dimulai dengan FIREBASE_
- Kunci apa pun dari daftar berikut:
- CLOUD_RUNTIME_CONFIG
- ENTRY_POINT
- GCP_PROJECT
- GCLOUD_PROJECT
- GOOGLE_CLOUD_PROJECT
- FUNCTION_TRIGGER_TYPE
- FUNCTION_NAME
- FUNCTION_MEMORY_MB
- FUNCTION_TIMEOUT_SEC
- FUNCTION_IDENTITY
- FUNCTION_REGION
- FUNCTION_TARGET
- FUNCTION_SIGNATURE_TYPE
- K_SERVICE
- K_REVISION
- PORT
- K_CONFIGURATION
Menyimpan dan mengakses informasi konfigurasi yang sensitif
Variabel lingkungan yang disimpan dalam file .env
dapat digunakan untuk konfigurasi fungsi, tetapi tidak boleh dianggap sebagai cara yang aman untuk menyimpan informasi sensitif seperti kredensial database atau kunci API. Hal ini penting jika Anda melakukan check in file .env
ke dalam kontrol sumber.
Untuk membantu Anda menyimpan informasi konfigurasi yang sensitif, Cloud Functions for Firebase terintegrasi dengan Google Cloud Secret Manager. Layanan terenkripsi ini menyimpan nilai konfigurasi dengan aman, sekaligus mengizinkan akses mudah dari fungsi Anda saat diperlukan.
Membuat dan menggunakan secret
Untuk membuat secret, gunakan Firebase CLI.
Untuk membuat dan menggunakan secret:
Dari root direktori project lokal, jalankan perintah berikut:
firebase functions:secrets:set SECRET_NAME
Masukkan nilai untuk SECRET_NAME.
CLI akan menampilkan pesan berhasil dan memperingatkan bahwa Anda harus men-deploy fungsi agar perubahan diterapkan.
Sebelum men-deploy, pastikan kode fungsi Anda mengizinkan fungsi tersebut mengakses secret menggunakan parameter
runWith
:Node.js
const { onRequest } = require("functions/v2/https"); exports.processPayment = onRequest( { secrets: ["SECRET_NAME"] }, (req, res) => { const myBillingService = initializeBillingService( // reference the secret value process.env.SECRET_NAME ); // Process the payment } );
Python (pratinjau)
import os from firebase_functions import https_fn @https_fn.on_request(secrets=["SECRET_NAME"]) def process_payment(req): myBillingService = initialize_billing(key=os.environ.get('SECRET_NAME')) # Process the payment ...
Deploy Cloud Functions:
firebase deploy --only functions
Sekarang Anda dapat mengaksesnya seperti variabel lingkungan lainnya. Sebaliknya, jika fungsi lain yang tidak menentukan secret dalam
runWith
mencoba mengakses secret, fungsi tersebut akan menerima nilai yang tidak ditentukan:Node.js
exports.anotherEndpoint = onRequest((request, response) => { response.send(`The secret API key is ${process.env.SECRET_NAME}`); // responds with "The secret API key is undefined" because the `runWith` parameter is missing });
Python (pratinjau)
@https_fn.on_request() def another_endpoint(req): return https_fn.Response(f"The secret API key is {os.environ.get("SECRET_NAME")}") # Responds with "The secret API key is None" because the `secrets` parameter is missing.
Setelah di-deploy, fungsi tersebut akan memiliki akses ke nilai secret. Hanya fungsi yang secara khusus menyertakan secret dalam parameter runWith
-nya yang akan memiliki akses ke secret tersebut sebagai variabel lingkungan. Cara ini membantu Anda memastikan bahwa nilai secret hanya tersedia di tempat yang diperlukan, sehingga mengurangi risiko kebocoran secret secara tidak sengaja.
Mengelola secret
Gunakan Firebase CLI untuk mengelola secret Anda. Saat mengelola secret dengan cara ini, perlu diingat bahwa beberapa perubahan CLI mengharuskan Anda untuk mengubah dan/atau men-deploy ulang fungsi-fungsi terkait. Secara khusus:
- Setiap kali Anda menetapkan nilai baru untuk secret, Anda harus men-deploy ulang semua fungsi yang merujuk ke secret tersebut agar fungsi dapat mengambil nilai terbaru.
- Jika Anda menghapus secret, pastikan tidak ada satu pun fungsi yang di-deploy merujuk ke secret tersebut. Fungsi yang menggunakan nilai secret yang telah dihapus akan gagal tanpa ada peringatan.
Berikut adalah ringkasan perintah Firebase CLI untuk pengelolaan secret:
# Change the value of an existing secret firebase functions:secrets:set SECRET_NAME # View the value of a secret functions:secrets:access SECRET_NAME # Destroy a secret functions:secrets:destroy SECRET_NAME # View all secret versions and their state functions:secrets:get SECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
Untuk perintah access
dan destroy
, Anda dapat memberikan parameter versi opsional untuk mengelola versi tertentu. Contoh:
functions:secrets:access SECRET_NAME[@VERSION]
Untuk mengetahui informasi selengkapnya tentang operasi ini, teruskan -h
dengan perintah untuk melihat bantuan CLI.
Cara penagihan secret
Secret Manager mengizinkan 6 versi secret aktif tanpa biaya. Artinya, Anda dapat memiliki 6 secret per bulan di project Firebase tanpa biaya.
Secara default, Firebase CLI berupaya secara otomatis menghancurkan versi secret yang tidak digunakan jika perlu, seperti ketika Anda men-deploy fungsi dengan versi secret baru. Selain itu, Anda dapat secara aktif membersihkan secret yang tidak digunakan menggunakan functions:secrets:destroy
dan functions:secrets:prune
.
Secret Manager mengizinkan 10.000 operasi akses bulanan yang tidak ditagih untuk sebuah secret. Instance fungsi hanya membaca secret yang ditentukan dalam parameter runWith
-nya setiap kali cold start dilakukan padanya. Jika Anda memiliki banyak instance fungsi yang membaca banyak secret, project Anda dapat melebihi kuota ini, dan setelah itu Anda akan dikenai biaya $0,03 per 10.000 operasi akses.
Untuk mengetahui informasi selengkapnya, lihat Harga Secret Manager.
Dukungan emulator
Konfigurasi lingkungan dengan dotenv dirancang agar dapat saling beroperasi dengan emulator Cloud Functions lokal.
Saat menggunakan emulator Cloud Functions lokal, Anda dapat mengganti variabel lingkungan untuk project dengan menyiapkan file .env.local
. Konten .env.local
lebih diutamakan daripada .env
dan file .env
khusus project.
Misalnya, project dapat menyertakan tiga file ini yang berisi nilai yang sedikit berbeda untuk pengembangan dan pengujian lokal:
.env
|
.env.dev
|
.env.local
|
PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Local Humans |
Saat dimulai dalam konteks lokal, emulator akan memuat variabel lingkungan seperti yang ditunjukkan berikut ini:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Secret dan kredensial di emulator Cloud Functions
Emulator Cloud Functions mendukung penggunaan secret untuk menyimpan dan mengakses informasi konfigurasi yang sensitif. Secara default, emulator akan mencoba mengakses secret production Anda menggunakan kredensial default aplikasi. Dalam situasi tertentu seperti lingkungan CI, emulator mungkin gagal mengakses nilai secret karena pembatasan izin.
Serupa dengan dukungan emulator Cloud Functions untuk variabel lingkungan, Anda dapat mengganti nilai secret dengan menyiapkan file .secret.local
. Hal ini memudahkan Anda untuk menguji fungsi secara lokal, terutama jika tidak memiliki akses ke nilai secret.
Bermigrasi dari konfigurasi lingkungan
Jika menggunakan konfigurasi lingkungan dengan functions.config
, Anda dapat memigrasikan konfigurasi yang ada sebagai variabel lingkungan (dalam format dotenv).
Firebase CLI menyediakan perintah ekspor yang menghasilkan output konfigurasi setiap alias atau project yang tercantum dalam file .firebaserc
direktori Anda (dalam contoh di bawah, local
, dev
, dan prod
) sebagai file .env
.
Untuk melakukan migrasi, ekspor konfigurasi lingkungan yang ada menggunakan perintah firebase functions:config:export
:
firebase functions:config:export i Importing configs from projects: [project-0, project-1] ⚠ The following configs keys could not be exported as environment variables: ⚠ project-0 (dev): 1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.) Enter a PREFIX to rename invalid environment variable keys: CONFIG\_ ✔ Wrote functions/.env.prod ✔ Wrote functions/.env.dev ✔ Wrote functions/.env.local ✔ Wrote functions/.env
Perhatikan bahwa, dalam beberapa kasus, Anda akan diminta untuk memasukkan awalan guna mengganti nama kunci variabel lingkungan yang diekspor. Ini karena tidak semua konfigurasi dapat diubah secara otomatis karena mungkin tidak valid atau merupakan kunci variabel lingkungan yang dicadangkan.
Sebaiknya tinjau dengan cermat konten file .env
yang dihasilkan sebelum men-deploy fungsi atau lakukan check in file .env
ke dalam kontrol sumber. Jika ada nilai yang sensitif dan tidak boleh bocor, hapus nilai tersebut dari file .env
Anda dan simpan dengan aman di Secret Manager.
Anda juga harus memperbarui kode fungsi. Setiap fungsi yang menggunakan functions.config
sekarang harus menggunakan process.env
, seperti yang ditunjukkan dalam Variabel lingkungan.