1. nesil Node.js işlevlerini 2. nesle yükseltme

Şu anda 1. nesil işlevleri kullanan uygulamaların, bu kılavuzda verilen talimatları kullanarak 2. nesile geçmesi önerilir. 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'u kullanır.

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

Taşıma süreci

1. nesil ve 2. nesil işlevler aynı dosyada yan yana bulunabilir. Bu sayede, hazır olduğunuzda parça parça kolayca taşıyabilirsiniz. Devam etmeden önce test ve doğrulama yaparak işlevleri tek tek taşımanızı öneririz.

Firebase CLI ve firebase-function sürümlerini doğrulama

En az Firebase CLI 12.00 sürümü ve firebase-functions 4.3.0 sürümünü kullandığınızdan emin olun. Daha yeni sürümler 1. nesil ve 2. nesil cihazları destekler.

İçe aktarmaları güncelleme

2. nesil işlevler, firebase-functions SDK'sındaki v2 alt paketinden içe aktarılır. Firebase CLI'ın, işlev kodunuzu 1. nesil işlev olarak mı yoksa 2. nesil işlev olarak mı dağıtacağını belirlemesi için gereken tek şey bu farklı içe aktarma yoludur.

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

Önce: 1. nesil

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

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üncelleme

2. nesil SDK modüler içe aktarma işlemlerini tercih ettiğinden, tetikleyici tanımlarını önceki adımdaki değiştirilen içe aktarma işlemlerini yansıtacak şekilde güncelleyin.

Bazı tetikleyiciler için geri çağırma işlevlerine iletilen bağımsız değişkenler değişti. Bu örnekte, onDocumentCreated geri çağırma işlevinin bağımsız değişkenlerinin tek bir event nesnesine birleştirildiğini unutmayın. 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/v1");

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 yapılandırmayı kullanma

2. nesil işlevler, kod tabanınızda yapılandırma parametrelerini açık bir şekilde tanımlamak için daha güvenli bir arayüz sunmak amacıyla functions.config desteğini sonlandırıyor. Yeni params modülüyle CLI, tüm parametrelerin geçerli bir değeri olmadığı sürece dağıtımı engeller. Böylece bir işlevin eksik yapılandırmayla dağıtılmaması sağlanır.

params alt paketine taşıma

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

Önce: 1. nesil

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

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

  // ...
});

2. nesil sonrası

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 ayarlama

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

Daha fazla güvenlik için parametre türlerini ve doğrulama kurallarını da belirtebilirsiniz.

Özel durum: API Anahtarları

params modülü, API anahtarları gibi hassas değerlere hassas erişim denetimi sağlayan Cloud Secret Manager ile entegre olur. Daha fazla bilgi için gizli parametreler bölümüne bakın.

Önce: 1. nesil

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

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ırılması 1. ve 2. nesil arasında değişti. 2. nesil, tüm işlevler için seçenekleri ayarlama konusunda yeni bir özellik de ekliyor.

Önce: 1. nesil

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

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) => {
    // ...
  });

2. nesil sonrası

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ığı kullanma

2. nesil işlevlerinin ö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ığı baştan başlatma sayısını önemli ölçüde azaltabilir. Eşzamanlılık varsayılan olarak 80 olarak ayarlanmıştır ancak 1 ila 1.000 arasında herhangi bir değere ayarlanabilir:

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

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

Eşzamanlılığı ayarlamak, performansı artırabilir ve işlevlerin maliyetini düşürebilir. Eşzamanlı isteklere izin ver bölümünde eşzamanlılık hakkında daha fazla bilgi edinin.

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

Eşzamanlılık göz önünde bulundurularak yazılmayan 1. nesil işlevler, her istekte ayarlanan ve okunan global değişkenler 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 genel değişkenleri ayarlamaya ve okumaya başladığından işlevinizde hatalar oluşabilir.

Yükseltme işlemi sırasında, işlevinizin CPU'sunu gcf_gen1 olarak ve concurrency değerini 1 olarak ayarlayarak 1. nesil davranışı geri yükleyebilirsiniz:

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

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

Ancak 2. nesil işlevlerin performans avantajlarından vazgeçildiği için bu, uzun vadeli bir çözüm olarak önerilmez. Bunun yerine, işlevlerinizde global 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şlevlerine taşıyın

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

Aynı ada sahip bir işlevi 1. nesilden 2. nesile yükseltmek ve firebase deploy çalıştırmak mümkün değildir. Aksi takdirde aşağıdaki hata meydana gelir:

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, işlevinizin hem yeni hem de eski sürümü değişiklik sırasında aynı anda çalışacağından işlevinizin tekil olduğundan emin olun. Örneğin, Firestore'daki yazma etkinliklerine yanıt veren 1. nesil bir işleviniz varsa bu etkinliklere yanıt olarak yazma işlemine 1. nesil işlev tarafından bir kez, 2. nesil işlev tarafından bir kez yanıt vererek uygulamanızın tutarlı bir durumda kalmasını sağlayın.

  1. İşlev kodunuzda işlevi yeniden adlandırın. Örneğin, resizeImage dosyasını resizeImageSecondGen olarak yeniden adlandırın.
  2. İşlevi, hem orijinal 1. nesil fonksiyonu hem de 2. nesil fonksiyonu çalışacak şekilde dağıtın.
    1. Çağırılabilir, Görev Kuyruğu ve HTTP tetikleyicileri söz konusu olduğunda, istemci kodunu 2. nesil işlevin adıyla veya URL'siyle güncelleyerek tüm istemcileri 2. nesil işleve yönlendirmeye başlayın.
    2. Arka plan tetikleyicileri kullanıldığında hem 1. nesil hem de 2. nesil işlevler, dağıtıldıktan hemen sonra her etkinliğe yanıt verir.
  3. Tüm trafik taşındığında firebase CLI'sinin firebase functions:delete komutunu kullanarak 1. nesil işlevini silin.
    1. İsteğe bağlı olarak 2. nesil işlevi, 1. nesil işlevin adıyla eşleşecek şekilde yeniden adlandırabilirsiniz.