1. nesil Node.js işlevlerini 2. nesile yükseltin

Şu anda 1. nesil işlevleri kullanan uygulamalar, bu kılavuzdaki talimatları kullanarak 2. nesile geçmeyi düşünmelidir. 2. nesil işlevler daha iyi performans, daha iyi yapılandırma, daha iyi izleme ve daha fazlasını sağlamak için Cloud Run'ı kullanır.

Bu sayfadaki örneklerde, JavaScript'i CommonJS modülleriyle birlikte kullandığınız varsayılmaktadır (stil içe aktarma require ), ancak aynı ilkeler ESM'li JavaScript ( import … from stil içe aktarmalarından) ve TypeScript için de geçerlidir.

Geçiş süreci

1. nesil ve 2. nesil işlevler aynı dosyada yan yana bulunabilir. Bu, siz hazır olduğunuzda parça parça kolayca geçiş yapmanızı sağlar. Her seferinde bir işlevi taşımanızı, devam etmeden önce test ve doğrulama yapmanızı öneririz.

Firebase CLI ve firebase-function sürümlerini doğrulayın

En azından Firebase CLI sürüm 12.00 ve firebase-functions sürüm 4.3.0 kullandığınızdan emin olun. Daha yeni sürümler 1. neslin yanı sıra 2. nesli de destekleyecektir.

İçe aktarmaları güncelle

firebase-functions SDK'sındaki v2 alt paketinden 2. nesil işlevler içe aktarılır. Bu farklı içe aktarma yolu, Firebase CLI'nin işlev kodunuzu 1. veya 2. nesil işlev olarak dağıtıp dağıtmayacağını belirlemek için ihtiyaç duyduğu tek şeydir.

v2 alt paketi modülerdir ve yalnızca ihtiyacınız olan belirli modülü içe aktarmanızı öneririz.

Önce: 1. nesil

const functions = require("firebase-functions");

Sonra: 2. nesil

// explicitly import each trigger
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

Tetikleyici tanımlarını güncelleyin

2. nesil SDK modüler içe aktarmaları desteklediğinden, tetikleyici tanımlarını önceki adımdaki değişen içe aktarmaları yansıtacak şekilde güncelleyin.

Bazı tetikleyiciler için geri aramalara aktarılan argümanlar değişti. Bu örnekte, onDocumentCreated geri çağrısına ilişkin argümanların tek bir event nesnesinde birleştirildiğine dikkat edin. Ayrıca bazı tetikleyiciler, onRequest tetikleyicisinin cors seçeneği gibi kullanışlı yeni yapılandırma özelliklerine sahiptir.

Önce: 1. nesil

const functions = require("firebase-functions");

exports.date = functions.https.onRequest((req, res) => {
  // ...
});

exports.uppercase = functions.firestore
  .document("my-collection/{docId}")
  .onCreate((change, context) => {
    // ...
  });

Sonra: 2. nesil

const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

exports.date = onRequest({cors: true}, (req, res) => {
  // ...
});

exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
  /* ... */
});

Parametreli konfigürasyon kullan

2. nesil işlevler, kod tabanınız içinde yapılandırma parametrelerini bildirimli olarak tanımlamak için daha güvenli bir arayüz lehine, functions.config desteğini bırakır. Yeni params modülüyle CLI, tüm parametrelerin geçerli bir değeri olmadığı sürece dağıtımı engeller ve bir işlevin eksik yapılandırmayla dağıtılmamasını sağlar.

params alt paketine geçiş

functions.config ile ortam yapılandırmasını kullanıyorsanız mevcut yapılandırmanızı parametreli yapılandırmaya taşıyabilirsiniz.

Önce: 1. nesil

const functions = require("firebase-functions");

exports.date = functions.https.onRequest((req, res) => {
  const date = new Date();
  const formattedDate =
date.toLocaleDateString(functions.config().dateformat);

  // ...
});

Sonra: 2. nesil

const {onRequest} = require("firebase-functions/v2/https");
const {defineString} = require("firebase-functions/params");

const dateFormat = defineString("DATE_FORMAT");

exports.date = onRequest((req, res) => {
  const date = new Date();
  const formattedDate = date.toLocaleDateString(dateFormat.value());

  // ...
});

Parametre değerlerini ayarlayın

Firebase CLI, ilk dağıtımınızda parametrelerin tüm değerlerini ister ve değerleri bir dotenv dosyasına kaydeder. Function.config değerlerinizi dışa aktarmak için firebase functions:config:export çalıştırın.

Ek güvenlik için parametre türlerini ve doğrulama kurallarını da belirleyebilirsiniz.

Özel durum: API Anahtarları

params modülü, API anahtarları gibi hassas değerlere ayrıntılı erişim kontrolü sağlayan Cloud Secret Manager ile entegre olur. Daha fazla bilgi için gizli parametrelere bakın.

Önce: 1. nesil

const functions = require("firebase-functions");

exports.getQuote = functions.https.onRequest(async (req, res) => {
  const quote = await fetchMotivationalQuote(functions.config().apiKey);
  // ...
});

Sonra: 2. nesil

const {onRequest} = require("firebase-functions/v2/https");
const {defineSecret} = require("firebase-functions/params");

// Define the secret parameter
const apiKey = defineSecret("API_KEY");

exports.getQuote = onRequest(
  // make the secret available to this function
  { secrets: [apiKey] },
  async (req, res) => {
    // retrieve the value of the secret
    const quote = await fetchMotivationalQuote(apiKey.value());
    // ...
  }
);

Çalışma zamanı seçeneklerini ayarlama

Çalışma zamanı seçeneklerinin yapılandırması 1. ve 2. nesil arasında değişti. 2. nesil ayrıca tüm işlevlere yönelik seçenekleri ayarlamaya yönelik yeni bir özellik de ekliyor.

Önce: 1. nesil

const functions = require("firebase-functions");

exports.date = functions
  .runWith({
    // Keep 5 instances warm for this latency-critical function
    minInstances: 5,
  })
  // locate function closest to users
  .region("asia-northeast1")
  .https.onRequest((req, res) => {
    // ...
  });

exports.uppercase = functions
  // locate function closest to users and database
  .region("asia-northeast1")
  .firestore.document("my-collection/{docId}")
  .onCreate((change, context) => {
    // ...
  });

Sonra: 2. nesil

const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
const {setGlobalOptions} = require("firebase-functions/v2");

// locate all functions closest to users
setGlobalOptions({ region: "asia-northeast1" });

exports.date = onRequest({
    // Keep 5 instances warm for this latency-critical function
    minInstances: 5,
  }, (req, res) => {
  // ...
});

exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
  /* ... */
});

Eşzamanlılık kullan

2. nesil işlevlerin önemli bir avantajı, tek bir işlev örneğinin aynı anda birden fazla isteğe hizmet verebilmesidir. Bu, son kullanıcıların yaşadığı soğuk başlatma sayısını önemli ölçüde azaltabilir. Varsayılan olarak eşzamanlılık 80'e ayarlıdır, ancak bunu 1'den 1000'e kadar herhangi bir değere ayarlayabilirsiniz:

const {onRequest} = require("firebase-functions/v2/https");

exports.date = onRequest({
    // set concurrency value
    concurrency: 500
  },
  (req, res) => {
    // ...
});

Eşzamanlılığın ayarlanması performansı artırabilir ve işlevlerin maliyetini azaltabilir. Eşzamanlı isteklere izin verme bölümünde eşzamanlılık hakkında daha fazla bilgi edinin.

Genel değişken kullanımını denetleyin

Eşzamanlılık göz önünde bulundurulmadan yazılan 1. nesil işlevler, her istekte ayarlanan ve okunan genel değişkenleri kullanabilir. Eşzamanlılık etkinleştirildiğinde ve tek bir örnek aynı anda birden fazla isteği işlemeye başladığında, eşzamanlı istekler aynı anda küresel değişkenleri ayarlamaya ve okumaya başladığından, bu durum işlevinizde hatalara neden olabilir.

Yükseltme sırasında işlevinizin CPU'sunu gcf_gen1 olarak ayarlayabilir ve 1. nesil davranışını geri yüklemek için concurrency 1'e ayarlayabilirsiniz:

const {onRequest} = require("firebase-functions/v2/https");

exports.date = onRequest({
    // TEMPORARY FIX: remove concurrency
    cpu: "gcf_gen1",
    concurrency: 1
  },
  (req, res) => {
    // ...
});

Ancak bu, 2. nesil işlevlerin performans avantajlarını ortadan kaldırdığı için uzun vadeli bir çözüm olarak önerilmez. Bunun yerine, işlevlerinizdeki genel değişkenlerin kullanımını denetleyin ve hazır olduğunuzda bu geçici ayarları kaldırın.

Trafiği yeni 2. nesil işlevlere taşıyın

Tıpkı bir işlevin bölgesini veya tetikleyici türünü değiştirirken olduğu gibi, 2. nesil işleve de yeni bir ad vermeniz ve trafiği yavaş yavaş ona taşımanız gerekir.

Bir işlevi aynı ada sahip 1. nesilden 2. nesle yükseltmek ve firebase deploy çalıştırmak mümkün değildir. Bunu yapmak hatayla sonuçlanacaktır:

Upgrading from GCFv1 to GCFv2 is not yet supported. Please delete your old function or wait for this feature to be ready.

Bu adımları uygulamadan önce öncelikle fonksiyonunuzun idempotent olduğundan emin olun çünkü değişiklik sırasında fonksiyonunuzun hem yeni sürümü hem de eski sürümü aynı anda çalışacaktır. Örneğin, Firestore'da yazma olaylarına yanıt veren bir 1. nesil işleviniz varsa, bu olaylara yanıt olarak bir yazmaya iki kez (bir kez 1. nesil işlev tarafından ve bir kez de 2. nesil işlev tarafından) yanıt verilmesinin uygulamanızı bir durumda bıraktığından emin olun. tutarlı durum.

  1. İşlev kodunuzdaki işlevi yeniden adlandırın. Örneğin, resizeImage resizeImageSecondGen olarak yeniden adlandırın.
  2. Hem orijinal 1. nesil işlevi hem de 2. nesil işlevi çalışacak şekilde işlevi dağıtın.
    1. Çağrılabilir, Görev Kuyruğu ve HTTP tetikleyicileri durumunda, istemci kodunu 2. nesil işlevin adı veya URL'siyle güncelleyerek tüm istemcileri 2. nesil işleve yönlendirmeye başlayın.
    2. Arka plan tetikleyicileri sayesinde hem 1. nesil hem de 2. nesil işlevler, dağıtımdan hemen sonra her olaya yanıt verecektir.
  3. Tüm trafik kapatıldığında, firebase CLI'nin firebase functions:delete komutunu kullanarak 1. nesil işlevi silin.
    1. İsteğe bağlı olarak, 2. nesil işlevi, 1. nesil işlevin adıyla eşleşecek şekilde yeniden adlandırın.