पहली जनरेशन के फ़ंक्शन इस्तेमाल करने वाले ऐप्लिकेशन को, दूसरी जनरेशन पर माइग्रेट करने के बारे में सोचना चाहिए. इसके लिए, इस गाइड में दिए गए निर्देशों का इस्तेमाल करें. दूसरी जनरेशन के फ़ंक्शन, 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");
ट्रिगर की परिभाषाएं अपडेट करना
दूसरी जनरेशन के एसडीके में मॉड्यूलर इंपोर्ट को प्राथमिकता दी जाती है. इसलिए, ट्रिगर की परिभाषाओं को अपडेट करें, ताकि पिछले चरण में किए गए इंपोर्ट में हुए बदलाव दिख सकें.
कुछ ट्रिगर के लिए, कॉलबैक को पास किए गए आर्ग्युमेंट बदल गए हैं. इस उदाहरण में ध्यान दें कि 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
मॉड्यूल की मदद से, सीएलआई तब तक डिप्लॉयमेंट को ब्लॉक करता है, जब तक सभी पैरामीटर की वैल्यू मान्य नहीं हो जाती. इससे यह पक्का किया जा सकता है कि किसी फ़ंक्शन को कॉन्फ़िगरेशन के बिना डिप्लॉय न किया जाए.
params
सब-पैकेज पर माइग्रेट करना
अगर functions.config
के साथ एनवायरमेंट कॉन्फ़िगरेशन का इस्तेमाल किया जा रहा है, तो मौजूदा कॉन्फ़िगरेशन को पैरामीटर वाले कॉन्फ़िगरेशन पर माइग्रेट किया जा सकता है.
पहले: पहली जनरेशन
const functions = require("firebase-functions/v1");
exports.date = functions.https.onRequest((req, res) => {
const date = new Date();
const formattedDate =
date.toLocaleDateString(functions.config().dateformat);
// ...
});
इसके बाद: दूसरी जनरेशन
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 फ़ाइल में सेव करेगी. functions.config वैल्यू एक्सपोर्ट करने के लिए, firebase functions:config:export
चलाएं.
ज़्यादा सुरक्षा के लिए, पैरामीटर के टाइप और पुष्टि करने के नियम भी तय किए जा सकते हैं.
खास मामला: एपीआई कुंजियां
params
मॉड्यूल, Cloud Secret Manager के साथ इंटिग्रेट होता है. यह एपीआई पासकोड जैसी संवेदनशील वैल्यू के लिए, बेहतर ऐक्सेस कंट्रोल उपलब्ध कराता है. ज़्यादा जानकारी के लिए, सीक्रेट पैरामीटर देखें.
पहले: पहली जनरेशन
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());
// ...
}
);
रनटाइम के विकल्प सेट करना
पहली और दूसरी जनरेशन के बीच, रनटाइम के विकल्पों के कॉन्फ़िगरेशन में बदलाव किया गया है. दूसरी जनरेशन में, सभी फ़ंक्शन के लिए विकल्प सेट करने की नई सुविधा भी जोड़ी गई है.
पहले: पहली जनरेशन
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) => {
/* ... */
});
कॉन्करेंसी का इस्तेमाल करना
दूसरी जनरेशन के फ़ंक्शन का एक अहम फ़ायदा यह है कि एक फ़ंक्शन इंस्टेंस, एक साथ एक से ज़्यादा अनुरोधों को पूरा कर सकता है. इससे असली उपयोगकर्ताओं को होने वाली कोल्ड स्टार्ट की समस्याओं को काफ़ी हद तक कम किया जा सकता है. डिफ़ॉल्ट रूप से, एक साथ किए जा सकने वाले अनुरोधों की संख्या 80 पर सेट होती है. हालांकि, इसे 1 से 1,000 के बीच की किसी भी संख्या पर सेट किया जा सकता है:
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
कमांड का इस्तेमाल करके, पहली जनरेशन के फ़ंक्शन को मिटा दें.- इसके अलावा, दूसरी जनरेशन के फ़ंक्शन का नाम बदलकर, पहली जनरेशन के फ़ंक्शन के नाम से मैच किया जा सकता है.