पहली जनरेशन के फ़ंक्शन का इस्तेमाल करने वाले ऐप्लिकेशन को, इस गाइड में दिए गए निर्देशों के मुताबिक दूसरी जनरेशन के फ़ंक्शन पर माइग्रेट करना चाहिए. दूसरी जनरेशन के फ़ंक्शन, 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 सबपैकेज मॉड्यूलर है. हमारा सुझाव है कि सिर्फ़ उस मॉड्यूल को इंपोर्ट करें जिसकी आपको ज़रूरत है.
इससे पहले: पहली जनरेशन
const functions = require("firebase-functions/v1");
इसके बाद: दूसरी जनरेशन
// explicitly import each trigger
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
ट्रिगर की परिभाषाएं अपडेट करना
दूसरी जनरेशन के SDK में मॉड्यूलर इंपोर्ट को प्राथमिकता दी जाती है. इसलिए, पिछले चरण में किए गए इंपोर्ट में हुए बदलावों को दिखाने के लिए, ट्रिगर की परिभाषाएं अपडेट करें.
कुछ ट्रिगर के लिए, कॉलबैक को पास किए गए आर्ग्युमेंट बदल गए हैं. इस उदाहरण में, ध्यान दें कि onDocumentCreated कॉलबैक के आर्ग्युमेंट को एक ही event ऑब्जेक्ट में शामिल कर दिया गया है. इसके अलावा, कुछ ट्रिगर में कॉन्फ़िगरेशन की नई और सुविधाजनक सुविधाएं जोड़ी गई हैं. जैसे, onRequest ट्रिगर का cors विकल्प.
इससे पहले: पहली जनरेशन
const functions = require("firebase-functions/v1");
exports.date = functions.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions.firestore
.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
इसके बाद: दूसरी जनरेशन
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 मॉड्यूल की मदद से, CLI तब तक डिप्लॉयमेंट को ब्लॉक करता है, जब तक सभी पैरामीटर की वैल्यू मान्य न हो. इससे यह पक्का होता है कि कोई फ़ंक्शन, कॉन्फ़िगरेशन के बिना डिप्लॉय न हो.
इससे पहले: पहली जनरेशन
const functions = require("firebase-functions/v1");
exports.getQuote = functions.https.onRequest(async (req, res) => {
const quote = await fetchMotivationalQuote(functions.config().apiKey);
// ...
});
इसके बाद: दूसरी जनरेशन
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());
// ...
}
);
अगर आपके पास functions.config के साथ मौजूदा एनवायरमेंट कॉन्फ़िगरेशन है, तो दूसरी जनरेशन में अपग्रेड करने के दौरान, इस कॉन्फ़िगरेशन को माइग्रेट करें.
functions.config API को बंद कर दिया गया है. इसे मार्च 2027 में पूरी तरह से बंद कर दिया जाएगा.
इसके बाद, functions.config के साथ किए गए डिप्लॉयमेंट काम नहीं करेंगे.
डिप्लॉयमेंट में होने वाली गड़बड़ियों से बचने के लिए, Firebase CLI का इस्तेमाल करके अपने कॉन्फ़िगरेशन को Cloud Secret Manager पर माइग्रेट करें. हमारा सुझाव है कि कॉन्फ़िगरेशन को माइग्रेट करने के लिए, इस तरीके का इस्तेमाल करें. यह सबसे सुरक्षित और असरदार तरीका है.
CLI की मदद से कॉन्फ़िगरेशन एक्सपोर्ट करनाFirebase
मौजूदा एनवायरमेंट कॉन्फ़िगरेशन को Cloud Secret Manager में नए सीक्रेट में एक्सपोर्ट करने के लिए,
config exportकमांड का इस्तेमाल करें:$ firebase functions:config:export i This command retrieves your Runtime Config values (accessed via functions.config()) and exports them as a Secret Manager secret. i Fetching your existing functions.config() from your project... ✔ Fetched your existing functions.config(). i Configuration to be exported: ⚠ This may contain sensitive data. Do not share this output. { ... } ✔ What would you like to name the new secret for your configuration? RUNTIME_CONFIG ✔ Created new secret version projects/project/secrets/RUNTIME_CONFIG/versions/1```सीक्रेट बाइंड करने के लिए, फ़ंक्शन कोड अपडेट करना
Cloud Secret Manager में नए सीक्रेट में सेव किए गए कॉन्फ़िगरेशन का इस्तेमाल करने के लिए, अपने फ़ंक्शन सोर्स में
defineJsonSecretAPI का इस्तेमाल करें. साथ ही, पक्का करें कि सीक्रेट, उन सभी फ़ंक्शन से बाइंड हों जिन्हें उनकी ज़रूरत है.इससे पहले
const functions = require("firebase-functions/v1"); exports.myFunction = functions.https.onRequest((req, res) => { const apiKey = functions.config().someapi.key; // ... });इसके बाद
const { onRequest } = require("firebase-functions/v2/https"); const { defineJsonSecret } = require("firebase-functions/params"); const config = defineJsonSecret("RUNTIME_CONFIG"); exports.myFunction = onRequest( // Bind secret to your function { secrets: [config] }, (req, res) => { // Access secret values via .value() const apiKey = config.value().someapi.key; // ... });फ़ंक्शन डिप्लॉय करना
बदलावों को लागू करने और सीक्रेट की अनुमतियां बाइंड करने के लिए, अपडेट किए गए फ़ंक्शन डिप्लॉय करें.
firebase deploy --only functions:<your-function-name>
रनटाइम के विकल्प सेट करना
पहली और दूसरी जनरेशन के बीच, रनटाइम के विकल्पों का कॉन्फ़िगरेशन बदल गया है. दूसरी जनरेशन में, सभी फ़ंक्शन के लिए विकल्प सेट करने की नई सुविधा भी जोड़ी गई है.
इससे पहले: पहली जनरेशन
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) => {
// ...
});
इसके बाद: दूसरी जनरेशन
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) => {
/* ... */
});
डिफ़ॉल्ट सेवा खाता अपडेट करना (ज़रूरी नहीं)
पहली जनरेशन के फ़ंक्शन, Firebase API के ऐक्सेस को अनुमति देने के लिए, Google App Engine के डिफ़ॉल्ट सेवा खाते का इस्तेमाल करते हैं. वहीं, दूसरी जनरेशन के फ़ंक्शन, Compute Engine के डिफ़ॉल्ट सेवा खाते का इस्तेमाल करते हैं. इस अंतर की वजह से, दूसरी जनरेशन में माइग्रेट किए गए फ़ंक्शन के लिए, अनुमति से जुड़ी समस्याएं हो सकती हैं. ऐसा तब होता है, जब आपने पहली जनरेशन के सेवा खाते को खास अनुमतियां दी हों. अगर आपने सेवा खाते की अनुमतियों में कोई बदलाव नहीं किया है, तो इस चरण को छोड़ा जा सकता है.
हमारा सुझाव है कि पहली जनरेशन के मौजूदा App Engine के डिफ़ॉल्ट सेवा खाते को उन फ़ंक्शन के लिए साफ़ तौर पर असाइन करें जिन्हें दूसरी जनरेशन में माइग्रेट करना है. इससे, दूसरी जनरेशन के डिफ़ॉल्ट सेवा खाते की जगह, पहली जनरेशन का सेवा खाता इस्तेमाल किया जाएगा. इसके लिए, पक्का करें कि माइग्रेट किए गए हर फ़ंक्शन में serviceAccountEmail के लिए सही वैल्यू सेट की गई हो:
const {onRequest} = require("firebase-functions/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
const {setGlobalOptions} = require("firebase-functions");
// Use the App Engine default service account for all functions
setGlobalOptions({serviceAccountEmail: '<my-project-number>@<wbr>appspot.gserviceaccount.com'});
// Now I use the App Engine default service account.
exports.date = onRequest({cors: true}, (req, res) => {
// ...
});
// I do too!
exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
// ...
});
इसके अलावा, सेवा खाते की जानकारी में बदलाव करके, यह पक्का किया जा सकता है कि App Engine के डिफ़ॉल्ट सेवा खाते (पहली जनरेशन के लिए) और Compute Engine के डिफ़ॉल्ट सेवा खाते (दूसरी जनरेशन के लिए), दोनों में सभी ज़रूरी अनुमतियां मौजूद हों.
कॉन्करेंसी का इस्तेमाल करना
दूसरी जनरेशन के फ़ंक्शन का एक अहम फ़ायदा यह है कि एक ही फ़ंक्शन इंस्टेंस, एक साथ एक से ज़्यादा अनुरोधों को पूरा कर सकता है. इससे, एंड यूज़र के लिए कोल्ड स्टार्ट की संख्या में काफ़ी कमी आ सकती है. डिफ़ॉल्ट रूप से, कॉन्करेंसी 80 पर सेट होती है. हालांकि, इसे 1 से 1000 के बीच किसी भी वैल्यू पर सेट किया जा सकता है:
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// set concurrency value
concurrency: 500
},
(req, res) => {
// ...
});
कॉन्करेंसी को ऑप्टिमाइज़ करने से, परफ़ॉर्मेंस बेहतर हो सकती है और फ़ंक्शन की लागत कम हो सकती है. कॉन्करेंसी के बारे में ज़्यादा जानने के लिए, एक साथ कई अनुरोधों की अनुमति देना लेख पढ़ें.
ग्लोबल वैरिएबल के इस्तेमाल की जांच करना
पहली जनरेशन के ऐसे फ़ंक्शन जिनमें कॉन्करेंसी का इस्तेमाल नहीं किया गया है उनमें ग्लोबल वैरिएबल का इस्तेमाल किया जा सकता है. इन वैरिएबल को हर अनुरोध पर सेट और पढ़ा जाता है. जब कॉन्करेंसी चालू होती है और एक ही इंस्टेंस, एक साथ कई अनुरोधों को मैनेज करना शुरू करता है, तो आपके फ़ंक्शन में गड़बड़ियां आ सकती हैं. ऐसा इसलिए, क्योंकि एक साथ कई अनुरोधों से ग्लोबल वैरिएबल को एक साथ सेट और पढ़ा जाता है.
अपग्रेड करते समय, अपने फ़ंक्शन के सीपीयू को 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) => {
// ...
});
हालांकि, लंबे समय तक इस तरीके का इस्तेमाल करने का सुझाव नहीं दिया जाता. ऐसा इसलिए, क्योंकि इससे दूसरी जनरेशन के फ़ंक्शन की परफ़ॉर्मेंस से जुड़े फ़ायदों का नुकसान होता है. इसके बजाय, अपने फ़ंक्शन में ग्लोबल वैरिएबल के इस्तेमाल की जांच करें. साथ ही, जब चाहें तब इन अस्थायी सेटिंग को हटाएं.
ट्रैफ़िक को दूसरी जनरेशन के नए फ़ंक्शन पर माइग्रेट करना
किसी फ़ंक्शन को पहली से दूसरी जनरेशन में अपग्रेड करने के लिए, उसे वही नाम नहीं दिया जा सकता और firebase deploy कमांड नहीं चलाया जा सकता. ऐसा करने पर, यह गड़बड़ी दिखेगी:
Upgrading from GCFv1 to GCFv2 is not yet supported. Please delete your old function or wait for this feature to be ready.
इन चरणों को पूरा करने से पहले, पक्का करें कि आपका फ़ंक्शन आइडमपोटेंट हो. ऐसा इसलिए, क्योंकि बदलाव के दौरान, आपके फ़ंक्शन का नया और पुराना, दोनों वर्शन एक साथ काम करेंगे. उदाहरण के लिए, अगर आपके पास पहली जनरेशन का कोई फ़ंक्शन है जो Firestore में लिखने के इवेंट पर प्रतिक्रिया देता है, तो पक्का करें कि उन इवेंट के जवाब में, पहली जनरेशन का फ़ंक्शन और दूसरी जनरेशन का फ़ंक्शन, दोनों एक-एक बार प्रतिक्रिया दें. इससे आपका ऐप्लिकेशन एक जैसी स्थिति में बना रहेगा.
- अपने फ़ंक्शन कोड में, फ़ंक्शन का नाम बदलें. उदाहरण के लिए,
resizeImageका नाम बदलकरresizeImageSecondGenकरें. - फ़ंक्शन को डिप्लॉय करें, ताकि पहली जनरेशन का ओरिजनल फ़ंक्शन और दूसरी जनरेशन का फ़ंक्शन, दोनों काम करें.
- कॉल किए जा सकने वाले, टास्क क्यू, और एचटीटीपी ट्रिगर के मामले में, क्लाइंट कोड को दूसरी जनरेशन के फ़ंक्शन के नाम या यूआरएल से अपडेट करके, सभी क्लाइंट को दूसरी जनरेशन के फ़ंक्शन पर पॉइंट करना शुरू करें.
- बैकग्राउंड ट्रिगर के साथ, पहली और दूसरी जनरेशन के फ़ंक्शन, दोनों हर इवेंट पर डिप्लॉयमेंट के तुरंत बाद प्रतिक्रिया देंगे.
- जब सारा ट्रैफ़िक माइग्रेट हो जाए, तो firebase CLI के
firebase functions:deleteकमांड का इस्तेमाल करके, पहली जनरेशन के फ़ंक्शन को मिटाएं.- ज़रूरत पड़ने पर, दूसरी जनरेशन के फ़ंक्शन का नाम बदलकर, पहली जनरेशन के फ़ंक्शन के नाम से मैच करें.