1st gen Node.js फ़ंक्शन को 2nd gen पर अपग्रेड करना

फ़िलहाल, 1st gen के फ़ंक्शन का इस्तेमाल करने वाले ऐप्लिकेशन को इस गाइड में दिए गए निर्देशों के हिसाब से 2nd gen पर माइग्रेट करना चाहिए. 2nd gen के फ़ंक्शन, Cloud Run का इस्तेमाल करते हैं, ताकि बेहतर परफ़ॉर्मेंस, कॉन्फ़िगरेशन, और मॉनिटर करने जैसे कई काम किए जा सकें.

इस पेज पर दिए गए उदाहरणों के हिसाब से, CommonJS मॉड्यूल (require स्टाइल इंपोर्ट) के साथ JavaScript का इस्तेमाल किया जा रहा है. हालांकि, ESM (import … from स्टाइल इंपोर्ट) और TypeScript के साथ JavaScript पर भी यही सिद्धांत लागू होते हैं.

माइग्रेशन की प्रोसेस

एक ही फ़ाइल में 1st gen और 2nd gen के फ़ंक्शन, अगल-बगल में मौजूद हो सकते हैं. इसकी मदद से, माइग्रेट करने की प्रोसेस को अलग-अलग हिस्सों में आसानी से माइग्रेट किया जा सकता है, हमारा सुझाव है कि आगे बढ़ने से पहले, एक बार में एक ही फ़ंक्शन को माइग्रेट करें. साथ ही, टेस्टिंग और पुष्टि करें.

Firebase सीएलआई और firebase-function के वर्शन की पुष्टि करें

पक्का करें कि Firebase सीएलआई वर्शन 12.00 और firebase-functions वर्शन 4.3.0 का इस्तेमाल किया जा रहा हो. इसका कोई भी नया वर्शन, 2nd gen के साथ 1st gen के साथ काम करेगा.

इंपोर्ट अपडेट करें

2nd gen के फ़ंक्शन, firebase-functions SDK टूल में मौजूद v2 सबपैकेज से इंपोर्ट किए जाते हैं. Firebase सीएलआई को इस अलग इंपोर्ट पाथ की मदद से यह तय करना होता है कि आपके फ़ंक्शन कोड को पहले जनरेट करने के फ़ंक्शन के तौर पर डिप्लॉय किया जाए या दूसरे जनरेशन के.

v2 सबपैकेज मॉड्यूलर है. हमारा सुझाव है कि आप सिर्फ़ उस मॉड्यूल को इंपोर्ट करें जिसकी आपको ज़रूरत है.

पहले: 1st gen

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

बाद में: 2nd gen

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

ट्रिगर की परिभाषाएं अपडेट करें

दूसरी पीढ़ी का SDK टूल, मॉड्यूलर इंपोर्ट का इस्तेमाल करता है. इसलिए, ट्रिगर की परिभाषाएं अपडेट करें, ताकि पिछले चरण में हुए इंपोर्ट को दिखाया जा सके.

कुछ ट्रिगर के लिए कॉलबैक को दिए गए आर्ग्युमेंट बदल गए हैं. इस उदाहरण में, ध्यान दें कि onDocumentCreated कॉलबैक के आर्ग्युमेंट, एक event ऑब्जेक्ट में इकट्ठा किए गए हैं. इसके अलावा, कुछ ट्रिगर में कॉन्फ़िगरेशन से जुड़ी नई सुविधाएं मिलती हैं, जैसे कि onRequest ट्रिगर का cors विकल्प.

पहले: 1st gen

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

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

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

बाद में: 2nd gen

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

पैरामीटर वाले कॉन्फ़िगरेशन का इस्तेमाल करें

2nd gen फ़ंक्शन, आपके कोड बेस में कॉन्फ़िगरेशन पैरामीटर को साफ़ तौर पर तय करने के लिए, ज़्यादा सुरक्षित इंटरफ़ेस के लिए functions.config के साथ काम करता है. नए params मॉड्यूल से, सीएलआई तब तक डिप्लॉयमेंट को ब्लॉक करता है, जब तक सभी पैरामीटर की एक मान्य वैल्यू न हो. इससे यह पक्का होता है कि कोई फ़ंक्शन, किसी बिना कॉन्फ़िगरेशन के डिप्लॉय नहीं किया गया है.

params सबपैकेज पर माइग्रेट करें

अगर functions.config के साथ एनवायरमेंट कॉन्फ़िगरेशन का इस्तेमाल किया जा रहा है, तो अपने मौजूदा कॉन्फ़िगरेशन को पैरामीटर वाले कॉन्फ़िगरेशन में माइग्रेट किया जा सकता है.

पहले: 1st gen

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

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

  // ...
});

बाद में: 2nd gen

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());

  // ...
});

पैरामीटर वैल्यू को सेट करना

पहली बार डिप्लॉय करने पर, Firebase सीएलआई, पैरामीटर की सभी वैल्यू के लिए प्रॉम्प्ट करता है और वैल्यू को dotenv फ़ाइल में सेव करता है. फ़ंक्शन.config की अपनी वैल्यू एक्सपोर्ट करने के लिए, firebase functions:config:export चलाएं.

ज़्यादा सुरक्षा के लिए, पैरामीटर के टाइप और पुष्टि करने के नियम भी तय किए जा सकते हैं.

खास मामला: एपीआई पासकोड

params मॉड्यूल को Cloud Secret Manager के साथ इंटिग्रेट किया जाता है, जो कि एपीआई पासकोड जैसी संवेदनशील वैल्यू का सटीक ऐक्सेस कंट्रोल देता है. ज़्यादा जानकारी के लिए, सीक्रेट पैरामीटर देखें.

पहले: 1st gen

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

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

बाद में: 2nd gen

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

रनटाइम के विकल्प सेट करें

रनटाइम के विकल्पों का कॉन्फ़िगरेशन, पहली और दूसरी जनरेशन के बीच बदल गया है. 2nd gen में सभी फ़ंक्शन के लिए विकल्प सेट करने की नई सुविधा जोड़ी गई है.

पहले: 1st gen

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

बाद में: 2nd gen

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

एक साथ कई वैल्यू का इस्तेमाल करने की सुविधा

2nd gen फ़ंक्शन का एक बड़ा फ़ायदा यह है कि एक फ़ंक्शन इंस्टेंस में एक साथ एक से ज़्यादा अनुरोध पूरे किए जा सकते हैं. इससे असली उपयोगकर्ताओं को कोल्ड स्टार्ट की समस्या बहुत कम हो सकती है. डिफ़ॉल्ट रूप से, कई वैल्यू को एक साथ 80 पर सेट किया जाता है. हालांकि, इसे 1 से 1,000 के बीच की कोई भी वैल्यू सेट की जा सकती है:

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

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

एक साथ सिंक करने की सुविधा का इस्तेमाल करने से, परफ़ॉर्मेंस बेहतर हो सकती है और फ़ंक्शन की लागत कम हो सकती है. एक साथ किए जाने वाले अनुरोधों को अनुमति दें में जाकर, एक साथ कई काम करने के अनुरोधों के बारे में ज़्यादा जानें.

ऑडिट में ग्लोबल वैरिएबल के इस्तेमाल की जानकारी

कई वैल्यू को एक साथ जोड़े बिना लिखे गए 1st gen के फ़ंक्शन, ऐसे ग्लोबल वैरिएबल का इस्तेमाल कर सकते हैं जो हर अनुरोध पर सेट होते हैं और पढ़े जाते हैं. जब एक साथ कई अनुरोध करने की सुविधा चालू होती है और एक इंस्टेंस एक साथ कई अनुरोधों को हैंडल करना शुरू करता है, तो इससे आपके फ़ंक्शन में गड़बड़ियां आ सकती हैं. ऐसा तब होता है, जब एक साथ किए जाने वाले अनुरोध एक साथ ग्लोबल वैरिएबल सेट करना और पढ़ना शुरू कर देते हैं.

अपग्रेड करते समय, अपने फ़ंक्शन के सीपीयू को gcf_gen1 पर सेट किया जा सकता है. साथ ही, 1st gen के व्यवहार को पहले जैसा करने के लिए, concurrency को 1 पर सेट किया जा सकता है:

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

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

हालांकि, इसे लंबे समय तक इस्तेमाल करने का सुझाव नहीं दिया जाता, क्योंकि इससे 2nd gen के फ़ंक्शन की परफ़ॉर्मेंस पर बुरा असर पड़ता है. इसके बजाय, अपने फ़ंक्शन में ग्लोबल वैरिएबल के इस्तेमाल का ऑडिट करें और जब आप तैयार हों, तो कुछ समय के लिए सेट की गई इन सेटिंग को हटा दें.

ट्रैफ़िक को 2nd gen के नए फ़ंक्शन पर माइग्रेट करना

किसी फ़ंक्शन का क्षेत्र या ट्रिगर टाइप बदलते समय, आपको 2nd gen फ़ंक्शन को नया नाम देना होगा और ट्रैफ़िक को धीरे-धीरे इस पर माइग्रेट करना होगा.

एक ही नाम वाले फ़ंक्शन को 1st gen से 2nd gen में अपग्रेड नहीं किया जा सकता और firebase deploy को नहीं चलाया जा सकता. ऐसा करने पर यह गड़बड़ी दिखेगी:

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

इन चरणों को पूरा करने से पहले, पक्का करें कि आपका फ़ंक्शन idempoent है. इसकी वजह यह है कि बदलाव के दौरान, आपके फ़ंक्शन का नया और पुराना, दोनों वर्शन एक ही समय पर चलेंगे. उदाहरण के लिए, अगर आपके पास 1st gen का ऐसा फ़ंक्शन है जो Firestore में इवेंट लिखने का जवाब देता है, तो पक्का करें कि लिखा गया जवाब दो बार दिया जा रहा हो. जैसे, 1st gen फ़ंक्शन से और एक बार 2nd gen के फ़ंक्शन से. इसके बाद, उन इवेंट के लिए आपका ऐप्लिकेशन एक जैसा ही रहता है.

  1. अपने फ़ंक्शन कोड में फ़ंक्शन का नाम बदलें. उदाहरण के लिए, resizeImage का नाम बदलकर resizeImageSecondGen करें.
  2. फ़ंक्शन को डिप्लॉय करें, ताकि ओरिजनल 1st gen फ़ंक्शन और 2nd gen फ़ंक्शन, दोनों चालू हों.
    1. कॉल किए जा सकने वाले, टास्क की सूची, और एचटीटीपी ट्रिगर के मामले में, सभी क्लाइंट को 2nd gen फ़ंक्शन पर रीडायरेक्ट करना शुरू करें. इसके लिए, क्लाइंट कोड को 2nd gen के फ़ंक्शन के नाम या यूआरएल से अपडेट करें.
    2. बैकग्राउंड ट्रिगर की मदद से, 1st gen और 2nd gen, दोनों फ़ंक्शन हर इवेंट के लिए तुरंत जवाब देंगे.
  3. सारा ट्रैफ़िक माइग्रेट होने के बाद, Firebase सीएलआई के firebase functions:delete कमांड का इस्तेमाल करके 1st gen फ़ंक्शन को मिटाएं.
    1. इसके अलावा, 1st gen के फ़ंक्शन के नाम से मैच करने के लिए 2nd gen फ़ंक्शन का नाम बदला जा सकता है.