Bu kılavuzda, uzantılarınızı kullanımdan kaldırılan Firebase Extensions ortamından, kullanıcılarınızın kendi Cloud Functions ortamlarında yükleyip dağıttığı bir işlevselliğe taşıma adımları gösterilmektedir. Bu işlevsellik, Firebase (2. nesil) kod tabanında kullanılabilir.
Bu, önerilen taşıma yoludur. Firebase, resmi npm eşdeğerlerine sahip uzantıların bir listesini tutar. Bu kılavuz, kendi listenizi oluşturma konusunda size yol gösterir.
Bu kılavuzda, Stream Cloud Firestore to
BigQuery
uzantısı (firestore-bigquery-export) örnek olarak kullanılmıştır. Her bölüm, taşıma işleminden önce uzantının nasıl göründüğünü ve @firebase-function-kits/firestore-bigquery-export paketi olarak nasıl göründüğünü gösteren bir çalışma örneğiyle sona erer.
Uzantıları taşıma hakkında daha fazla bilgi ve yardım almak için kaydolun.
Firebase Extensions sürümünden nasıl geçiş yapacağınızla ilgili sorularınız varsa firebase-extensions-migrator-support-external@google.com adresinden bize ulaşabilirsiniz. Ayrıca, kılavuzu 2. nesil işlevlerinizi paketleme, test etme ve dağıtma hakkında daha fazla bilgiyle güncelledikçe bu gruba e-posta göndereceğiz.
Bu gruba katılmak için firebase-extensions-migrator-support-external+subscribe@google.com adresine mesaj gönderin. Bu adresten, üyelik isteği e-postasıyla yanıt alacaksınız. "Bu Gruba Katıl" düğmesini tıklamadan e-postayı yanıtlamanız gerekir.
Başlamadan önce
Bu taşıma işlemini belirtildiği şekilde tamamlamak için Cloud Functions'nın aşağıdaki özelliklerini kullanacaksınız:
Parametreli Yapılandırma.
extension.yamliçinde bildirdiğiniz her parametre, paket kodunuzda tanımlanmış bir parametre haline gelir.Bildirimli IAM rolleri ve gerekli API'ler.
extension.yamliçinde bildirdiğiniz her rol birrequiresRole(...)çağrısı, her API ise paket kodunuzda birrequiresAPI(...)çağrısı olur. Dağıtım sırasında Firebase KSA, bildirilen rolleri yönetilen bir çalışma zamanı hizmet hesabına verir ve bildirilen API'leri sizin adınıza etkinleştirir.Cloud Functions kod tabanları için yaşam döngüsü etkinlikleri Cloud Functions kod tabanları artık Firebase Extensions'ye benzer yaşam döngüsü etkinliklerini destekliyor. Yaşam döngüsü kancaları
afterFirstDeploy(...)veafterRedeploy(...)ile yükleme ve güncelleme zamanı kurulumunu tanımlayın. Bunlar,extension.yamliçinde tanımladığınızlifecycleEventsöğesinin yerini alır.
Firebase Extensions kaynağını 2. nesil bir işleve taşıma
(İsteğe bağlı) Firebase Agent Skill ile otomatik taşıma
Resmi extension-to-functions-codebase yapay zeka aracısı becerisini kullanarak 1 ila 8 arasındaki adımları (envanter kaynakları, yükseltmeleri tetikleme, param ve gizli dönüştürmeler, bildirimli IAM, yaşam döngüsü kancaları ve paket README'sini oluşturma) otomatikleştirebilirsiniz.
Beceriyi yükleyin
Siz veya yapay zeka kodlama asistanınız (Firebase'da Gemini, Cursor, Claude Code, GitHub Copilot) beceriyi henüz yüklemediyseniz beceri CLI'sını kullanarak aşağıdaki komutu çalıştırın:
npx skills add firebase/agent-skills --skill extension-to-functions-codebase
Beceri projenize yüklendikten sonra yapay zeka kodlama asistanınız, taşıma kurallarını ve dönüştürme adımlarını otomatik olarak uygular. Aşağıdaki istemi kullanabilirsiniz:
"Lütfen bu Firebase uzantısını extension-to-functions-codebase
becerisindeki talimatları uygulayarak yayınlanabilir bir 2. nesil işlev kiti paketine taşıyın.
becerisindeki talimatları uygulayarak yayınlanabilir bir 2. nesil işlev kiti paketine taşıyın."
1. Uzantıyı envantere ekleme
Uzantınızın envanterini çıkararak başlayın: Uzantının bildirdiği, gönderdiği ve belgelediği her şeyin tam listesi. Böylece her davranışın 2. nesil işlevde tanımlanmış bir hedefi olur ve taşıma sırasında hiçbir şey kaybolmaz.
Aşağıdakilerin her birini inceleyin ve bulgularınızı not edin:
Parametrelerinizi, işlevlerinizi, etkinliklerinizi, IAM rollerinizi, gerekli API'lerinizi, gizli dizilerinizi ve yaşam döngüsü kancalarınızı bildiren
extension.yaml.functions/. Bu dosya; işlev kodunuzu, bağımlılıklarınızı, derleme yapılandırmanızı, tetikleyicilerinizi ve görev sırası işlevlerinizi içerir.Kurulum adımları, uyarılar ve faturalandırma notları içeren
README.md,PREINSTALL.mdvePOSTINSTALL.md.scripts/; içe aktarma, doldurma, IAM, onarım veya taşıma yardımcı programlarının yanı sıra uzantıyla birlikte gönderdiğiniz diğer tüm araçları içerir.
Ardından, extension.yaml içindeki her öğenin npm paketinde nereye gideceğine karar verin:
Kullanıcı yapılandırmasını Cloud Functions parametrelerine dönüştürün (4. adım).
Gizli anahtarları Cloud Functions gizli anahtarlarına dönüştürün ( 4. adım).
IAM rollerini
requiresRole(...)beyanlarına dönüştürün (6. adım).Gerekli Google API'lerini uygun yerlerde
requiresAPI(...)beyanlarına dönüştürün (6. adım).Yükleme ve güncelleme kancalarını
afterFirstDeploy(...)veafterRedeploy(...)beyanlarına dönüştürün (7. adım).Örnek kimliklerini
EXT_INSTANCE_IDbiçimindenFIREBASE_KIT_INSTANCE_IDbiçimine dönüştürün (4. adım).
Çalışma örneği: Cloud Firestore'dan BigQuery'a yayın yapma
firestore-bigquery-export/extension.yaml ve functions/ ürünleri okunuyor.
Bu envanter oluşturuluyor:
extension.yaml içinde |
Sayı / değer | Nereye gider? |
|---|---|---|
params |
25 (COLLECTION_PATH, DATASET_ID, TABLE_ID, DATASET_LOCATION, VIEW_TYPE, …) |
Cloud Functions params (4. adım) |
apis |
bigquery.googleapis.com |
requiresAPI(...) (6. adım) |
roles |
bigquery.dataEditor, datastore.user, bigquery.user |
requiresRole(...) (6. adım) |
resources |
1 etkinlik tetikleyici (fsexportbigquery) + görev sırası işlevleri (initBigQuerySync, setupBigQuerySync) |
Dışa aktarılan paket işlevleri (3. adım) |
lifecycleEvents |
onInstall → initBigQuerySync; onUpdate / onConfigure → setupBigQuerySync |
afterFirstDeploy / afterRedeploy (7. adım) |
| Örnek Kimliği | Kullanılmıyor (EXT_INSTANCE_ID okuma yok) |
Taşınacak öğe yok |
scripts/ |
import/ (dolgu), gen-schema-view/ |
Komut dosyaları olarak saklananlar (burada kapsam dışıdır) |
Analiz. Uzantı herhangi bir type: secret parametresi bildirmediğinden 4. adımda gizli diziler için taşınacak bir şey yoktur. Etkinlik tetikleyici zaten 2. nesildir. Yalnızca görev sırası işlevleri hâlâ 1. nesildir (3. adımda önemlidir).
2. package.json dosyasını güncelleme
Uzantınızın package.json dosyasını güncelleyin. Tek bir uzantıyı taşıyorsanız bu, kök package.json olabilir. Tek bir depoda çok sayıda uzantı taşıyorsanız her uzantıya kendi paketini verin.
Minimum SDK sürümleri: firebase-functions >=
7.4.0 ve firebase-admin >=
14.2.0 bağımlılıklarını tanımlayın. Kullanıcılarınızın Cloud Functions projesinde, kitaplığınızın yazıldığı SDK'nın aynı
sürümü bulunması için firebase-functions sürümünüzü de eş
bağımlılık olarak beyan edin.
{
"name": "<package-name>",
"version": "1.0.0",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"default": "./lib/index.js"
}
},
"engines": {
"node": "22"
},
"peerDependencies": {
"firebase-functions": "^7.4.0"
},
"dependencies": {
"firebase-functions": "^7.4.0",
"firebase-admin": "^14.2.0"
}
}
Çalışma örneği: Cloud Firestore'dan BigQuery'a yayın yapma
Önce. Uzantının functions/package.json dosyası gizlidir, uzantı kimliğini adlandırır ve firebase-functions dosyasını doğrudan bağımlılık olarak bildirir:
{
"name": "firestore-bigquery-export",
"main": "lib/index.js",
"private": true,
"dependencies": {
"@firebaseextensions/firestore-bigquery-change-tracker": "^2.0.4",
"firebase-admin": "^14.2.0",
"firebase-functions": "^6.3.2"
}
}
Sonra. Yayınlanabilir bir paket: kapsamlı ad, exports haritası ve firebase-functions, peerDependencies'ye taşındı:
{
"name": "@firebase-function-kits/firestore-bigquery-export",
"version": "0.1.0",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"default": "./lib/index.js"
}
},
"engines": {
"node": "22"
},
"peerDependencies": {
"firebase-functions": "^7.4.0"
},
"dependencies": {
"@firebaseextensions/firestore-bigquery-change-tracker": "^2.0.4",
"firebase-admin": "^14.2.0",
"firebase-functions": "^7.4.0"
}
}
3. 1. nesilden 2. nesile yükseltme işlevleri
Uzantınız hâlâ 1. nesil işlevleri dışa aktarıyorsa her tetikleyiciyi 2. nesil eşdeğerine dönüştürün. firebase-functions/... modüllerinden içe aktarın ve tetikleyici seçeneklerinde çalışma zamanı ayarlarını iletin.
Cloud Functions 2. nesil yükseltme kılavuzuna bakın. Özellikle, 2. nesil yama uygulanmış etkinlik yapılarını kullanarak yeniden yazma çabalarını en aza indirebilirsiniz. Ayrıca, 2. nesil SDK, v1 parametrelerini etkinlik nesnesindeki alanlar olarak kullanıma sunduğundan işlev mantığınızı yeniden yazmaktan kaçınabilirsiniz. Bu sayede, yapıları bozulmuş/adlandırılmış parametreleri kullanabilir ve iş mantığınızı değiştirmeden tutabilirsiniz.
Önce. 1. nesil:
import * as functions from "firebase-functions/v1";
export const sync = functions.firestore
.document("{collectionId}/{documentId}")
.onWrite(async (change, context) => {
await handleWrite(change.before, change.after, context.params);
});
Sonra. 2. nesil:
import { onDocumentWritten } from "firebase-functions/firestore";
export const syncV2 = onDocumentWritten(
{ document: "{collectionId}/{documentId}" },
async ({ change, context }) =>
await handleWrite(change.before, change.after, context.params)
);
1. nesil ve 2. nesil işlevler arasındaki farkların kapsamlı listesi için Cloud Functions sürüm karşılaştırmasına bakın.
1. ve 2. nesil işlevler arasındaki önemli bir fark, 2. nesil işlevlerin tetikleyici kaynaklarıyla aynı konumda olması gerektiğidir. Kullanıcılar 1. nesil işlevleri kullanan bir uzantıdan 2. nesil işlevleri kullanan bir kitte geçiş yaptıklarında bu koşulu karşılamak için işlev konumlarını değiştirmeleri gerekebilir.
Kullanıcılarınızın seçtiği Cloud Functions konumları, mevcut konum korunacağından taşıma sırasında bozulabilir. Uzantınızın etkinliği tetikleyen işlevleri, kullanıcı tarafından sağlanan işlevlerin konumuna bağlıysa etkinlik tetikleme konumunu toplamak ve bunu yeni işlev konumuna eşlemek için uzantınıza yeni bir parametre eklemenizi öneririz.
Çalışma örneği: Cloud Firestore'dan BigQuery'a yayın yapma
defineString("DATABASE_REGION", {
label: "Firestore Instance Location",
description:
"Where is the Firestore database located? You can check your current database location at https://console.cloud.google.com/firestore/databases. The functions in this kit deploy to the Cloud Run region closest to this location.",
input: select({
"Multi-region (Europe - Belgium and Netherlands)": "eur3",
"Multi-region (United States)": "nam5",
"Multi-region (Iowa, North Virginia, and Oklahoma)": "nam7",
"Iowa (us-central1)": "us-central1",
// More locations...
})
});
// Firestore multi-region locations are not Cloud Run regions; deploying a
// function to one hard-fails, so they map to a region inside the multi-region.
const MULTI_REGION_TO_FUNCTION_REGION: Record<string, string> = {
nam5: "us-central1",
nam7: "us-central1",
eur3: "europe-west1",
};
/**
* Maps a Firestore database location to the Cloud Run region the functions
* should deploy to. The lookup is case-insensitive and ignores surrounding
* whitespace, as the CLI's own region handling is. Regional locations pass
* through lowercased; an unset or blank location returns `undefined`, meaning
* the functions declare no region.
*/
export function firestoreLocationToFunctionRegion(
location: string | undefined
): string | undefined {
const normalized = location?.trim().toLowerCase();
if (!normalized) {
return undefined;
}
return MULTI_REGION_TO_FUNCTION_REGION[normalized] ?? normalized;
}
const functionRegion = firestoreLocationToFunctionRegion(
process.env.DATABASE_REGION
);
export const fsexportbigquery = onDocumentWritten(
{
region: functionRegion,
// Other configuration
},
(event) => handleDocumentWrite(event, getHandlerContext())
);
Kit ilk kez dağıtıldığında kullanıcılardan DATABASE_REGION istenecektir ve işlevler, 2. nesil etkinlik tarafından tetiklenen işlevlerdeki konum sorunlarını düzelterek yukarıdaki ilgili functionRegion dağıtılacaktır.
4. Uzantı parametrelerini ve sırlarını dönüştürme
Parametreler
extension.yaml içinde tanımladığınız her parametre, Cloud Functions
parametreye dönüşür.
Doğrudan ortam okumalarını dönüştürme:
const collectionPath = process.env.COLLECTION_PATH;
Cloud Functions parametrelerine:
import { defineString } from "firebase-functions/params";
import { onDocumentWritten } from "firebase-functions/firestore";
const collectionPath = defineString("COLLECTION_PATH");
// Pass the param directly when used as a placeholder (e.g. trigger path)
export const sync = onDocumentWritten(
{ document: collectionPath },
async (event) => {
// Call .value() to read the string inside a handler
const path = collectionPath.value();
await handleWrite(path, event);
}
);
Bir işleyicinin içindeki dizeyi okumak için collectionPath.value(), yer tutucunun beklendiği yerlerde (ör. işlev tetikleme yolu) doğrudan collectionPath kullanın.
Firebase CLI, parametrelerinizi keşfeder ve değerlerini .env, .env.<projectId> veya dağıtım sırasında kullanıcılarınızdan okur. Mevcut bir kurulumdaki değerlerin aktarılması için aynı parametre adlarını kullanın.
Kodunuzda belirtilen parametre adlarını hiçbir şekilde değiştirmemeniz önemlidir. Uzantı taşıma işlemi, mevcut son kullanıcı parametre değerlerini otomatik olarak korur ancak yalnızca adlar değişmediğinde.
Çalışma örneği: Cloud Firestore'dan BigQuery'a yayın yapma
Önce. extension.yaml içinde tanımlanan ve config.ts içinde ham ortam değişkeni olarak okunan bir parametre:
# extension.yaml
- param: COLLECTION_PATH
label: Collection path
type: string
required: true
// functions/src/config.ts
collectionPath: process.env.COLLECTION_PATH,
Sonra. Bir defineString varsa KSA bunu keşfeder ve .env dosyasından okur:
// src/config.ts
import { defineString } from "firebase-functions/params";
collectionPath: defineString("COLLECTION_PATH", {
label: "Collection path",
// We now support "nonEmpty: true" to ensure a value other than the empty string
// is entered, analogous to "required: true" in extension.yaml
input: { text: { nonEmpty: true } }
}),
Parametre adı değişmediği için mevcut bir .env çalışmaya devam eder.
Örnek Kimliği
Uzantılar, örnek kimliklerini Uzantılar çalışma zamanı tarafından yerleştirilen EXT_INSTANCE_ID öğesinden okur. İşlev kitleri, örnek kimliklerini
FIREBASE_KIT_INSTANCE_ID konumundan okur. Firebase CLI, her bir kit
örneği için konumunu firebase.json içindeki instances haritasında örneğin anahtarı olarak ayarlar. CLI, dağıtım zamanı keşfi sırasında, emülatörde ve dağıtılan işlevlere bu bilgiyi sağlar.
Örnek kimliği bir parametre değildir. Bu nedenle, defineString ile bildirmeyin. Aslında, FIREBASE_..., .env dosyalarında ayrılmış bir önek olduğundan kullanıcılar bunu ayarlayamaz veya geçersiz kılamaz. CLI'nın yerleştirdiği değerler, params sistemine görünmez. Doğrudan ortamdan okuyun:
// Before
const instanceId = process.env.EXT_INSTANCE_ID;
// After
const instanceId = process.env.FIREBASE_KIT_INSTANCE_ID;
Değişken yalnızca paketiniz kit olarak dağıtıldığında ayarlanır. Kodunuz bağımsız bir kod tabanı olarak da dağıtılıyorsa (9. Adım'a bakın) isteğe bağlı olarak değerlendirin veya eksik olduğunda net bir mesajla hızlıca başarısız olun. Uzantınız örnek kimliğini kullanıcıya yönelik bir parametre olarak kullanıma sunuyorsa bu parametreyi kaldırmanız gerekir. Çünkü Firebase CLI artık bu değerin sahibidir.
Çalışma örneği: Kullanıcı verilerini silme
(Stream Cloud Firestore to BigQuery uzantısı, örnek kimliğini okumadığından burada taşınacak bir şey yoktur. Delete User Data (Kullanıcı Verilerini Sil) uzantısı, Pub/Sub konularını adlandırmak için bu bilgiyi kullanır.)
Önce. Uzantıların kaynakları için kullandığı ext- önekiyle config.ts içinde ham ortam değişkeni olarak okunur:
// functions/src/config.ts
discoveryTopic: `ext-${process.env.EXT_INSTANCE_ID}-discovery`,
deletionTopic: `ext-${process.env.EXT_INSTANCE_ID}-deletion`,
Sonra. Kullanıcıların konu adlarını geçersiz kılabilmesi için iki normal parametre için kullanılan basit bir process.env FIREBASE_KIT_INSTANCE_ID okuma işlemi:
// src/config.ts
const instanceId = process.env.FIREBASE_KIT_INSTANCE_ID;
// Non-empty defaults so Pub/Sub trigger bindings resolve during deploy
// discovery without freezing an empty topic name into the manifest.
discoveryTopicName: defineString("DISCOVERY_TOPIC_NAME", {
default: `kit-${instanceId}-discovery`,
}),
deletionTopicName: defineString("DELETION_TOPIC_NAME", {
default: `kit-${instanceId}-deletion`,
}),
Varsayılanlar boş olmamalıdır. Çünkü tetikleyici bağlamaları keşif sırasında çözülür. Boş bir varsayılan değer, dağıtım manifestine konu adı olarak yazılır. Kit, kit bağlamı dışında çalışmaya karşı da savunma sağlar. Değişken eksikse modül düzeyindeki varsayılan değer kit-undefined-discovery olarak değerlendirilir. Bu nedenle, yapılandırma yükleyici bunun yerine açıklayıcı bir hatayla başarısız olur:
// ...
const instanceId = process.env.FIREBASE_KIT_INSTANCE_ID;
if (!instanceId) {
throw new Error(
"FIREBASE_KIT_INSTANCE_ID is not set. It is provided automatically to " +
"kit instances by firebase-tools >= 15.32.0; deploy or emulate this " +
"kit with a supported CLI version."
);
}
// ...
Bu kontrol, bir işleyici yapılandırmasını ilk kez çözdüğünde çalışır. Bu nedenle, eksik bir değişken, kit-undefined-* konularına sessizce bağlı işlevler yerine net bir çalışma zamanı hatası üretir. Dağıtımı reddetmek için keşif sırasında çalışması amacıyla kontrolü modül kapsamında gerçekleştirin. CLI, örnek kimliğini firebase.json değerinden türettiği için yapılandırılabilir bir INSTANCE_ID yoktur ve birden fazla örnek arasında senkronize edilecek bir şey yoktur.
Gizli Anahtarlar
extension.yaml içinde type: secret ile sırları bildirirsiniz. Uzantı çalışma zamanı, uzantıları saklayıp bağlar. Böylece uzantı kodunuz process.env.PARAM_NAME öğesini doğrudan okuyabilir. Tipik bir Cloud Functions kod tabanında, her bir Gizli Anahtarı tanımlar ve bağlarsınız:
import { defineSecret } from "firebase-functions/params";
import { onRequest } from "firebase-functions/https";
const apiKey = defineSecret("API_KEY");
export const fn = onRequest({ secrets: [apiKey] }, handler);
Uzantınız bir npm paketine/kitine taşındıktan sonra gizli referanslar, son kullanıcının .env dosyasında yönetilir.
Kodunuzda belirtilen gizli adları hiçbir şekilde değiştirmemeniz önemlidir. Taşıma sırasında,
son kullanıcı sırları buna göre taşınır.
Çalışma örneği: Cloud Firestore adresinden e-posta tetikleme
Önce. MAIL_COLLECTION ve SMTP_PASSWORD, config.ts içinde ham ortam değişkenleri olarak okunur:
# extension.yaml
- param: MAIL_COLLECTION
label: Email documents collection
type: string
default: mail
required: true
- param: SMTP_PASSWORD
label: SMTP password
type: secret
// functions/src/config.ts
mailCollection: process.env.MAIL_COLLECTION,
smtpPassword: process.env.SMTP_PASSWORD,
Sonra. Bir defineString ve bir defineSecret; KSA her ikisini de keşfeder
ve .env'dan okur:
import { defineString, defineSecret } from "firebase-functions/params";
import { onDocumentWritten } from "firebase-functions/firestore";
const mailCollection = defineString("MAIL_COLLECTION", {
label: "Email documents collection",
default: "mail"
});
const smtpPassword = defineSecret("SMTP_PASSWORD", { label: "SMTP password" });
export const processQueue = onDocumentWritten(
{ document: `${mailCollection}/{documentId}`, secrets: [smtpPassword] },
async (event) => {
const collection = mailCollection.value();
const password = smtpPassword.value();
// ...
}
);
5. Dahili görev sırası çağrılarını taşıma
Bazı uzantılar, Firebase Admin SDK kullanarak işleri kendi görev kuyruklarına işlev kodlarının içinden ekler. Bu, gönderilen bir görevi almaktan farklıdır (Yükseltme işlevleri ve Dönüşüm yaşam döngüsü kancaları bölümlerinde ele alınmıştır). Burada kodunuz, queue.enqueue(...) işlevini çağıran üreticidir.
Admin SDK'nın önceki sürümlerinde, uzantıların aynı uzantıdaki bir görev sırası işlevini hedeflemek için kendi uzantı örneği kimliklerini ikinci bir parametre olarak iletmeleri gerekiyordu. firebase-admin 14.2.0 sürümünden itibaren bu işlem ne gereklidir ne de önerilir. Görev Kuyruğu API'si artık varsayılan olarak aynı bağlamdaki (ör. uzantı veya kit) görev kuyruklarını hedefler. Bu parametreyi kodunuzda hem uzantı hem de bağımsız işlevler olarak kaldırmak güvenlidir ve önerilir.
Bu parametrenin kaldırılması, taşınabilirlik ve ileriye dönük uyumluluk sağlar.
Kuyruğa alma çağrısıyla ilgili diğer her şey (locations/<region>/functions/<name> kaynak yolu, görev yükü ve yeniden deneme mantığınız) aynı kalır.
Cloud Tasks ile işlevleri sıraya alma hakkında daha fazla bilgi için Cloud Tasks ile işlevleri sıraya alma başlıklı makaleyi inceleyin.
Önce. 1. nesil uzantı:
import { getFunctions } from "firebase-admin/functions";
const queue = getFunctions().taskQueue(
`locations/${config.location}/functions/syncBigQuery`,
process.env.EXT_INSTANCE_ID, // extension instance ID, injected by the runtime
);
await queue.enqueue(taskData);
Sonra. 2. nesil uzantı:
import { getFunctions } from "firebase-admin/functions";
const queue = getFunctions().taskQueue(
`locations/${process.env.FUNCTION_REGION}/functions/syncBigQuery`
);
await queue.enqueue(taskData);
Sıraya ekleme çağrınız, önekli bir kod tabanını hedefliyorsa keşfedilen işlev adı da önekli olur (ör. orders-syncBigQuery). Değiştirme işlevi kiti örneğini inceleme ve yükleme ile İşlev kiti olarak test etme başlıklı makalelere bakın.
6. Gerekli API'leri ve IAM rollerini bildirme
Uzantınızın IAM ve API gereksinimlerini extension.yaml dışına taşıyıp kodun içine alın:
import { requiresAPI, requiresRole } from "firebase-functions";
requiresAPI("bigquery.googleapis.com", "Needed to write changelog rows");
requiresRole("roles/bigquery.dataEditor");
requiresRole("roles/bigquery.user");
Bildirim temelli güvenlik ile Firebase KSA, kod tabanı için yönetilen bir çalışma zamanı hizmet hesabı oluşturur veya günceller ve bu hesaba, bildirilen tüm rollerin birleşimini verir. Son API daha dar bir modeli desteklemediği sürece, kod tabanındaki tüm işlevlerin bu rollerle çalıştığını kullanıcılarınıza bildirin.
Çalışma örneği: Cloud Firestore'dan BigQuery'a yayın yapma
Önce. extension.yaml içinde belirtilir. Uzantılar çalışma zamanı, API'yi etkinleştirmiş ve rolleri yönetilen bir hesaba vermiştir:
apis:
- apiName: bigquery.googleapis.com
roles:
- role: bigquery.dataEditor
- role: datastore.user
- role: bigquery.user
Sonra. requiresAPI ve requiresRole ile kodda belirtilir:
import { requiresAPI, requiresRole } from "firebase-functions";
requiresAPI(
"bigquery.googleapis.com",
"Needed to write changelog rows and views"
);
requiresRole("roles/bigquery.dataEditor");
requiresRole("roles/datastore.user");
requiresRole("roles/bigquery.user");
Uzantınız Eventarc etkinlikleri yayınlıyorsa etkinlik yayınlamak için gerekli rolleri ve API'leri de ayarlamanız gerekir. Bu işlem daha önce extensions.yaml içinde herhangi bir değişiklik yapılmasına gerek kalmadan Uzantılar tarafından gerçekleştiriliyordu. Bunu kodunuzda koşullu olarak yapabilirsiniz. Böylece kit, yalnızca özel bir Eventarc kanalı kullanıldığında bu izinleri ister.
if (!!process.env.EVENTARC_CHANNEL) {
requiresRole("roles/eventarc.publisher");
requiresAPI(
"eventarcpublishing.googleapis.com",
"Publishes the extension's custom events to its Eventarc channel."
);
}
7. Yaşam döngüsüyle ilgili dikkat çekici girişleri dönüştürme
Uzantınız getExtensions().runtime() çağrısı yapıyorsa (örneğin,
setProcessingState veya setFatalError) bu çağrıları silin. Bu çağrılar, normal şekilde dağıtılan 2. nesil bir işlevden çağrıldığında hata verir. Yaşam döngüsü durumu artık afterFirstDeploy ve afterRedeploy tarafından belirleniyor. Bu durumda, durum takibi kullanılmıyor.
Firebase Extensions, kullanıcı bir uzantı yüklediğinde, güncellediğinde veya yeniden yapılandırdığında kurulumu çalıştırabilir. npm paketinize eşdeğer yaşam döngüsü işlemlerini kodda tanımlayın.
Tek seferlik kurulum için:
import { afterFirstDeploy } from "firebase-functions/lifecycle";
import { onTaskDispatched } from "firebase-functions/tasks";
export const runInitialSetup = onTaskDispatched(async (request) => {
await initializeResources(request.data);
});
afterFirstDeploy({
task: {
function: "runInitialSetup",
body: {}
}
});
Yapılandırma veya kod güncellemeleri için:
import { afterRedeploy } from "firebase-functions/lifecycle";
afterRedeploy({
task: {
function: "runInitialSetup",
body: { reconcile: true }
}
});
Yaşam döngüsü işlemlerinizi idempotent yapın. Gönderme veya yürütme işlemi başarısız olursa kullanıcılarınızın bu işlemleri manuel olarak yeniden çalıştırması gerekebilir:
firebase functions:lifecycle:run afterFirstDeploy CODEBASE_NAME
firebase functions:lifecycle:run afterRedeploy CODEBASE_NAME
Çalışma örneği: Cloud Firestore'dan BigQuery'a yayın yapma
Önce. Uzantılar çalışma zamanı tarafından desteklenen extension.yaml içindeki lifecycleEvents:
lifecycleEvents:
onInstall:
function: initBigQuerySync
processingMessage: Configuring BigQuery Sync.
onUpdate:
function: setupBigQuerySync
processingMessage: Configuring BigQuery Sync
onConfigure:
function: setupBigQuerySync
processingMessage: Configuring BigQuery Sync
Sonra. Kodda belirtilir. Görev, ilk dağıtımda BigQuery sağlar:
import { afterFirstDeploy, afterRedeploy } from "firebase-functions/lifecycle";
afterFirstDeploy({ task: { function: "initBigQuerySync" } });
afterRedeploy({ task: { function: "setupBigQuerySync" } });
Sağlama işlemi, aynı sonucu veren bir işlemdir. Bu nedenle, yeniden çalıştırma işlemi veri kümesini, tabloyu ve görünümleri uzlaştırır.
Kullanıcılar, firebase functions:lifecycle:run afterFirstDeploy
CODEBASE_NAME ile manuel olarak yeniden çalıştırabilir.
8. Kullanıcılarınız için doküman kurulumu
En azından aşağıdakileri açıklayan bir paket README yazın:
- Paketin gerektirdiği
.envdeğerleri. - Paketin gerektirdiği sırlar ve mevcut sır değerlerinin nasıl taşınacağı.
- Paketin
requiresRole(...)ile bildirdiği IAM rolleri. - Paketin etkinleştirdiği veya gerektirdiği Google API'leri.
- Paketin bildirdiği yaşam döngüsü kancaları ve bunların nasıl manuel olarak yeniden çalıştırılacağı.
- Faturalandırma notları.
- Orijinal uzantıya kıyasla ne değişti?
- Paketin örnek kimliğini (CLI tarafından ayarlanan
FIREBASE_KIT_INSTANCE_ID) nasıl aldığı ve tüm örnek işlevlerininkit-<instanceId>-önekiyle dağıtıldığı.
Çalışma örneği: Cloud Firestore'dan BigQuery'a yayın yapma
README paketi, "ne değişti" tablosunu gönderir:
| Endişe | Uzantı olarak | @firebase-function-kits/firestore-bigquery-export olarak |
|---|---|---|
| Yapılandırma | Uzantı parametreleri | Cloud Functions, .env üzerinden parametreler |
| IAM ile yönetin. | Uzantılar tarafından verilen izinler | requiresRole(...), dağıtım sırasında uygulandı |
| Temel hazırlık yapılıyor | Uzantılara göre yaşam döngüsü görevi | afterFirstDeploy / afterRedeploy görev |
| İşlev adları | ext-<instanceId>-fsexportbigquery |
fsexportbigquery (isteğe bağlı olarak önekli) |
| Örnek Kimliği | EXT_INSTANCE_ID uzantılar tarafından yerleştirilen |
FIREBASE_KIT_INSTANCE_ID, KSA tarafından firebase.json tarihinden itibaren ayarlanır. |
9. 2. nesil işlevinizi test etme
Artık, dağıtıldığında uzantınızın yeni yüklenmesiyle aynı şekilde çalışan 2. nesil bir işleviniz olmalıdır. Bir sonraki adım, bu süreçte yanlışlıkla ortaya çıkan sorunları doğrulayıp düzeltmektir.
Varsayılan bölge veya CPU gibi genel seçenekleri ayarlamak için setGlobalOptions'ı çağırmak istiyorsanız bunu yalnızca kitinizi bağımsız 2. nesil işlev olarak dağıtırken yapmanız gerekir. Kitiniz bir npm paketi olarak yüklendiğinde kullanıcılarınız bu parametreleri yapılandırmak için sarmalama kodlarında setGlobalOptions işlevini çağırır. Bu işlem iki kez gerçekleşirse kullanıcılar uyarı alır.
FIREBASE_KIT_INSTANCE_ID
ortam değişkenini kontrol ederek bu çağrıyı koruyabilirsiniz:
import { setGlobalOptions } from "firebase-functions";
if (!process.env.FIREBASE_KIT_INSTANCE_ID) {
setGlobalOptions({
region: "us-east1",
maxInstances: 10,
});
}
firebase-tools
>= 15.32.0 kullandığınızdan emin olun ve dönüştürülmüş 2. nesil işlevinizi davranışını test etmek için uygun kaynaklara sahip bir test projesine dağıtın. Uzantınızı test etmek için daha önce bir test projesi oluşturduysanız aşağıdaki komutu çalıştırın:
firebase deploy --only functions
Parametre değerlerini isteyen sonuçtaki sihirbazı, uzantı için Firebase konsolundaki kurulum formunu doldurmuş gibi doldurun.
Çalışma örneği: Cloud Firestore'dan BigQuery'a yayın yapma
Cloud Firestore ile BigQuery arasındaki senkronizasyonun uçtan uca olduğunu doğrularız:
- Firebase konsolunun Cloud Firestore sayfasında, henüz yoksa
COLLECTION_PATH(users) olarak ayarladığınız koleksiyonu oluşturun. - Herhangi bir değer içeren alanları içeren
bigquery-mirror-testadlı bir doküman oluşturun. BigQuery sayfasında, Google Cloud konsolunda ham değişiklik günlüğü tablosunu sorgulayın. Belge oluşturma işlemini kaydeden tek bir satır içermelidir:
SELECT * FROM `PROJECT_ID.analytics.users_raw_changelog`Yalnızca mevcut doküman için en son değişiklik etkinliğini döndürmesi gereken en son görünümü sorgulayın (
bigquery-mirror-test):SELECT * FROM `PROJECT_ID.analytics.users_raw_latest`Cloud Firestore içindeki
bigquery-mirror-testdokümanını silin. En son görünümden kaybolur ve ham değişiklik günlüğü tablosunaDELETEetkinliği eklenir.Tek bir dokümanın tüm geçmişini şu yöntemlerle inceleyebilirsiniz:
SELECT * FROM `PROJECT_ID.analytics.users_raw_changelog` WHERE document_name = "bigquery-mirror-test" ORDER BY timestamp ASC
Uzantıyı test etme işleminden farklılıklar:
- Tetikleyici,
fsexportbigquery(tipik bir 2. nesil işlev olarak dağıtılırken ve kit olarak dağıtılmazken ön ek yok) olarak dağıtılır,ext-<instanceId>-fsexportbigqueryolarak dağıtılmaz. Bu adı Cloud Functions kontrol panelinde ve günlüklerde bulun. - Kodunuz artık Firebase Local Emulator Suite'da normal işlevler gibi çalışıyor.
Parametrelerin değerini, emülatörde kullanılacak şekilde
.env.localile ayarlayabilirsiniz. Ayrıca, Birim testi Cloud Functions bölümünde açıklandığı gibifirebase-functions-testSDK'sını kullanarak kodunuzun birim testini de yapabilirsiniz. - Artık uzantılar çalışma zamanı tarafından sağlama yapılmıyor. Dağıtımdan sonra değişiklik günlüğü tablosu eksikse kurulum görevini manuel olarak yeniden çalıştırın:
firebase functions:lifecycle:run afterFirstDeploy CODEBASE_NAME. Görev, yinelemeli olduğundan yeniden çalıştırıldığında veri kümesi, tablo ve görünümler uzlaştırılır. - Parametre değerleri yükleme formundan değil
.envkaynağından alınır. Bu nedenle,.envtamamlandıktan sonrafirebase deployyeniden çalıştırıldığında etkileşimli olmaz.
10. İşlev kitinizi npm'de yayınlama
Uzantıdan 2. nesil işlevlere dönüşümünüzü doğruladıktan sonra, aşağıdaki kılavuzlardan birini kullanarak uçtan uca test için npm'ye yayın adayı yayınlayabilirsiniz:
- Kapsamı belirlenmemiş herkese açık paketler oluşturma ve yayınlama
- Kapsamlı herkese açık paketler oluşturma ve yayınlama
Kitiniz npm'de yayınlandığında firebase functions:kits:install ile yüklenebilir ve uzantınızın resmi alternatifi olarak listelenebilir.
Öncelikle sürüm adayı yayınlamanızı önemle tavsiye ederiz. Kitler, paket adı ve sürümüne göre yüklenir. Bu nedenle, yayın öncesi sürüm, varsayılan latest etiketiyle yükleme yapan kullanıcılara tamamlanmamış bir paket sunmadan gerçek yükleme akışını kayıt defterine göre test etmenize olanak tanır.
Yayınlamadan önce:
- Bir paket adı seçin. Hem kapsamlı hem de kapsamlı olmayan adlar çalışır (yukarıdaki kılavuzlara bakın). Kapsamlı paketlerin varsayılan olarak gizli olduğunu unutmayın. Bu nedenle,
--access publiciletin. - Hangi ürünlerin gönderileceğini oluşturun ve kontrol edin.
mainvetypes, derlenmiş çıktınızı ( çalışan örneğimizdekilib/) gösterir. Bu nedenle, dizin yayınlanan tar dosyasına dahil edilmelidir..npmignoreveyafilesizin verilenler listesi kullanın ve sonucunpm pack --dry-runile inceleyin. Derlemenizi çalıştıran birprepublishOnlykomut dosyası, eski çıkışın yayınlanmasını engeller.
Yayınlamayı varsayılan olarak güvenli hale getiren package.json eklemeleri:
{
"files": ["lib", "README.md", "CHANGELOG.md"],
"publishConfig": { "access": "public", "tag": "next" },
"scripts": {
"build": "tsc -b",
"prepublishOnly": "npm run build && npm test"
}
}
"publishConfig": { "tag": "next" } alanı, düz bir npm
publish öğesinin hiçbir zaman latest öğesinin üzerine yazmamasını sağlar.
Sürüm adayı oluşturma:
Örneğin, sürümü yerel olarak 0.0.2-rc.3'dan 0.0.2-rc.4'ye yükseltmek için
(package.json, depo kökündeyse bu işlem Git'te commit ve etiketleme yapar):
npm version prerelease --preid rc
Sürüm adayını yayınlamak ve @your-org/your-kit@0.0.2-rc.4'yı next etiketi altında npm'ye kaydetmek için:
npm publish
npm web sitesinin yeni sürümü göstermesi birkaç dakika sürebilir. npm view, kayıt defterini doğrudan okur:
npm view @your-org/your-kit versions dist-tags
Bu kılavuzdaki 11. adım ve 12. adım tamamlandıktan sonra paketi kararlı bir sürüme yükseltebilirsiniz:
npm version 0.0.2
npm publish --tag latest
npm dist-tag add @your-org/your-kit@0.0.2 next
npm-shrinkwrap.json ile ilgili not: Paketinizle birlikte bir npm-shrinkwrap.json dosyası eklemenizi önemle tavsiye ederiz. Aksi takdirde KSA, yükleme sırasında kullanıcıları uyarır. Bu özellik, kullanıcıların test ettiğiniz bağımlılıkları kullanmasını sağlar ve tedarik zinciri saldırılarına karşı korunmaya yardımcı olur. Ancak, Cloud Functions derlemesi (npm ci) sırasında da dahil olmak üzere, kullanıcılarınızın projelerinde shrinkwrap aynen uygulanır. Bu durumda, yalnızca geliştiricilere yönelik girişler EBADPLATFORM ile başarısız olabilir. Yayınlanan shrinkwrap kopyasından "dev": true girişlerini ve devDependencies öğelerini kaldırmanız gerekebilir.
Çalışma örneği: Cloud Firestore'dan BigQuery'a yayın yapma
Dördüncü sürüm adayı yayınlandığında kitteki package.json:
{
"name": "@firebase-function-kits/firestore-bigquery-export",
"version": "0.0.2-rc.4",
"repository": {
"type": "git",
"url": "https://github.com/firebase/extensions.git",
"directory": "kits/firestore-bigquery-export"
},
"main": "lib/index.js",
"types": "lib/index.d.ts",
"engines": { "node": "22" },
"scripts": { "build": "tsc -b" }
}
Bu durumda kitin tek depoda bulunduğunu unutmayın. Bu nedenle, npm kayıt bağlantısının doğru klasöre yönlendirilmesi için repository.directory eklemeniz önemlidir. CHANGELOG.md, bekleyen sürümle ilgili notları içerir.
11. İşlev kiti olarak test etme
Kitinizi yayınladıktan sonra npm kullanarak test etmenizi öneririz.
firebase-tools
>= 15.32.0 sürümünü kullandığınızdan emin olun ve kiti yükleyin:
firebase functions:kits:install --package <your-package-name>@<your-prerelease-version>
Bu işlem, paketinizi npm'den indirir, kitiniz için yeni bir kaynak dizininde kurar ve ilk örneği uzantı yükleme akışına benzer şekilde yapılandırma konusunda size yol gösterir. Paketinizi yerel olarak yükleyip kurduktan sonra Google Cloud projenizde kaynak oluşturmak için dağıtım yapın:
firebase deploy --only functions:<your-kit-instance-id>
Yüklemeden sonra Firebase CLI, yükleme sırasında seçtiğiniz tam örnek kimliğiyle benzer bir dağıtım komutu yazdırır.
9. adım bölümündeki talimatları kullanarak kitinizi tekrar doğrulayın. 2. nesil işlevinizi test edin. Artık kitleri kullanarak dağıtım yaptığınız için işlevleriniz kit-<instance-id>-<method-name> ön ekiyle adlandırılıyor. Bu sayede, kitler birden fazla örneğe sahip olabilir ve aynı işlevi bir projede birden çok kez dağıtabilir. Her örnek benzersiz bir ada sahiptir.
12. Test taşıma işlemini değiştirme
Çalışan bir uzantı örneği oluşturabilir ve ardından kullanıcı taşıma kılavuzunu (firebase ext:migrate --package veya işlev kiti CLI komutlarını kullanarak) kullanarak işlev kitinizi taşıma yerine geçecek şekilde test etmeyi tamamlayabilirsiniz.
13. Kullanıcıları ve Google'ı resmi uzantı değişikliğiniz hakkında bilgilendirin.
İşlev kiti değiştirme işleminiz tamamlanıp kullanıcıların geçmesi gereken bir npm paketi olarak kullanıma sunulduğunda hem kullanıcılarınızı hem de Google'ı bu resmi değiştirme işlemi hakkında bilgilendirin. Uzantınızı barındıran GitHub deposundaki README.md dosyasını aşağıdaki bilgilerle güncelleyin:
<!-- FIREBASE_EXTENSION_REPLACEMENT: extension="<your-extesion-id>" package="<your-npm-package-name>" -->
> [!WARNING]
> **Deprecation Notice:** The Firebase Extension `<your-extension>` is deprecated. Migrate to the [<your-npm-package-name>](<link-to-your-npm-package>) package.
Google, bilinen uzantı README'lerini <!--
FIREBASE_EXTENSION_REPLACEMENT: extension="firebase/firestore-bigquery-export"
package="@firebase-function-kits/firestore-bigquery-export" --> gibi yorumlar için tarar ve firebase-tools deposunda replacements.json olarak depolanan resmi yedek kayıt defterimizi doldurmak için bu bilgileri kullanır.
Uzantınız için hangi README.md öğelerinin taranacağını görmek üzere replacements.json işaretini de kontrol edebilirsiniz. Resmi yedek listesi haftalık olarak güncellenir.
Çalışma örneği: Cloud Firestore'dan BigQuery'a yayın yapma
firestore-bigquery-export uzantısı
README.md
şunları içerir:
<!-- FIREBASE_EXTENSION_REPLACEMENT: extension="firebase/firestore-bigquery-export" package="@firebase-function-kits/firestore-bigquery-export" -->
> [!WARNING]
> **Deprecation Notice:** The Firebase Extension `firebase/firestore-bigquery-export` is deprecated. Please migrate to the [`@firebase-function-kits/firestore-bigquery-export`](https://www.npmjs.com/package/@firebase-function-kits/firestore-bigquery-export) package.