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

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

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

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

पहले और दूसरे जनरेशन के फ़ंक्शन, एक ही फ़ाइल में एक साथ काम कर सकते हैं. इससे, आपके पास धीरे-धीरे माइग्रेट करने का विकल्प होता है. हमारा सुझाव है कि एक बार में एक फ़ंक्शन को माइग्रेट करें. साथ ही, आगे बढ़ने से पहले, उसकी जांच करें और पुष्टि करें.

Firebase CLI और firebase-function के वर्शन की पुष्टि करना

पक्का करें कि आपने Firebase CLI के कम से कम 12.00 वर्शन और firebase-functions के 4.3.0 वर्शन का इस्तेमाल किया हो. नया वर्शन, पहले और दूसरे जनरेशन, दोनों के साथ काम करेगा.

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

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

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

इससे पहले: 1st gen

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

बाद में: 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/v1");

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

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

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

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

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

पहले: 1st gen

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

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 CLI पैरामीटर की सभी वैल्यू के लिए प्रॉम्प्ट करता है और वैल्यू को dotenv फ़ाइल में सेव करता है. फ़ंक्शन.config की अपनी वैल्यू एक्सपोर्ट करने के लिए, firebase functions:config:export चलाएं.

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

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

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

इससे पहले: 1st gen

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

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

बाद में: 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) => {
  /* ... */
});

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

दूसरे जनरेशन के फ़ंक्शन का एक अहम फ़ायदा यह है कि एक फ़ंक्शन के एक ही इंस्टेंस से एक से ज़्यादा अनुरोधों को एक साथ पूरा किया जा सकता है. इससे, असली उपयोगकर्ताओं को कोल्ड स्टार्ट की संख्या में काफ़ी कमी आ सकती है. डिफ़ॉल्ट रूप से, एक साथ कई टास्क करने की सीमा 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 पर सेट किया जा सकता है. साथ ही, पहले जनरेशन के फ़ंक्शन के व्यवहार को वापस लाने के लिए, 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 फ़ंक्शन को नया नाम देना होगा और ट्रैफ़िक को धीरे-धीरे इस पर माइग्रेट करना होगा.

किसी फ़ंक्शन को एक ही नाम से पहले से दूसरे जनरेशन में अपग्रेड नहीं किया जा सकता और 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 है. इसकी वजह यह है कि बदलाव के दौरान, आपके फ़ंक्शन का नया और पुराना, दोनों वर्शन एक ही समय पर चलेंगे. उदाहरण के लिए, अगर आपके पास पहला जनरेशन फ़ंक्शन है, जो Firestore में डेटा लिखने से जुड़े इवेंट का जवाब देता है, तो पक्का करें कि डेटा लिखने के लिए, पहला जनरेशन फ़ंक्शन और दूसरा जनरेशन फ़ंक्शन, दोनों एक ही तरह से काम करें.

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