প্রায়শই আপনার ফাংশনের জন্য অতিরিক্ত কনফিগারেশন প্রয়োজন হবে, যেমন থার্ড-পার্টি API কী বা টিউন করা যায় এমন সেটিংস। Firebase-এর জন্য SDK Cloud Functions আপনার প্রোজেক্টের জন্য এই ধরনের ডেটা স্টোর ও রিট্রিভ করা সহজ করতে বিল্ট-ইন এনভায়রনমেন্ট কনফিগারেশন অফার করে।
আপনি এইসব বিকল্পের মধ্যে থেকে বেছে নিতে পারেন:
- প্যারামিটারাইজড কনফিগারেশন (বেশিরভাগ পরিস্থিতির জন্য সাজেস্ট করা হয়)। এটি প্যারামিটার সহ অত্যন্ত টাইপ করা এনভায়রনমেন্ট কনফিগারেশন প্রদান করে যা ডেপ্লয় করার সময় যাচাই করা হয়, এটি সমস্যা প্রতিরোধ করে এবং ডিবাগ করা সহজ করে তোলে।
- এনভায়রনমেন্ট ভেরিয়েবেল-এর ফাইল-ভিত্তিক কনফিগারেশন। এই পদ্ধতিতে, আপনি এনভায়রনমেন্ট ভেরিয়েবল লোড করার জন্য dotenv ফাইল ম্যানুয়ালি তৈরি করেন।
বেশিরভাগ ব্যবহারের ক্ষেত্রে, প্যারামিটারাইজড কনফিগারেশন সাজেস্ট করা হয়। এই পদ্ধতি রানটাইম ও ডিপ্লয় টাইম, উভয় ক্ষেত্রেই কনফিগারেশন ভ্যালু উপলভ্য করে তোলে এবং সব প্যারামিটারে সঠিক ভ্যালু না থাকলে ডিপ্লয়মেন্ট ব্লক করা হয়। অন্যদিকে, এনভায়রনমেন্ট ভেরিয়েবল সহ কনফিগারেশন ডিপ্লয় টাইমে উপলভ্য থাকে না।
প্যারামিটারাইজড কনফিগারেশন
Cloud Functions for Firebase আপনার কোডবেসের মধ্যে কনফিগারেশন প্যারামিটার ডিক্লেয়ার করার জন্য একটি ইন্টারফেস প্রদান করে। ফাংশন ডিপ্লয়মেন্ট, ডিপ্লয়মেন্ট ও রানটাইম বিকল্প সেট করা এবং এক্সিকিউশন, এই সবকটি সময় এইসব প্যারামিটারের ভ্যালু উপলভ্য থাকে। এর অর্থ হল, সব প্যারামিটারের সঠিক ভ্যালু না থাকলে CLI ডেপ্লয়মেন্ট ব্লক করে দেবে।
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineInt, defineString } = require('firebase-functions/params');
// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');
// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
# To use configured parameters inside the config for a function, provide them
# directly. To use them at runtime, call .value() on them.
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')
প্যারামিটারাইজড কনফিগারেশন ভেরিয়েবল সহ কোনও ফাংশন ডেপ্লয় করার সময়, Firebase CLI প্রথমে লোকাল .env ফাইল থেকে সেগুলির ভ্যালু লোড করার চেষ্টা করে। সেগুলি
ওইসব ফাইলে না থাকলে এবং কোনও default সেট করা না থাকলে, CLI ডিপ্লয়মেন্টের সময় ভ্যালু
প্রদান করতে বলবে এবং তারপরে আপনার functions/ ডিরেক্টরিতে .env.<project_ID> নামের একটি
.env ফাইলে অটোমেটিক তাদের ভ্যালু সেভ করবে:
$ firebase deploy
i functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i functions: Loaded environment variables from .env.projectId
আপনার ডেভেলপমেন্ট ওয়ার্কফ্লো অনুযায়ী, জেনারেট করা .env.<project_ID> ফাইলকে ভার্সন কন্ট্রোলে যোগ করা সহায়ক হতে পারে।
গ্লোবাল স্কোপে প্যারামিটার ব্যবহার করা
ডেপ্লয়মেন্টের সময়, আপনার ফাংশন কোড লোড করা হয় এবং আপনার
প্যারামিটারের আসল ভ্যালু থাকার আগে তা পরিদর্শন করা হয়। এর অর্থ হল, গ্লোবাল স্কোপে
প্যারামিটার ভ্যালু ফেচ করলে, ডিপ্লয়মেন্ট সম্পূর্ণ হবে না। যেসব ক্ষেত্রে আপনি কোনও গ্লোবাল ভ্যালু ইনিশিয়ালাইজ করার জন্য
প্যারামিটার ব্যবহার করতে চান, সেখানে ইনিশিয়ালাইজেশন কলব্যাক
onInit()ব্যবহার করুন। প্রোডাকশনে কোনও ফাংশন রান করার আগে এই কলব্যাক রান করে, কিন্তু
ডেপ্লয় করার সময় এটি কল করা হয় না, তাই প্যারামিটারের
ভ্যালু অ্যাক্সেস করার জন্য এটি একটি নিরাপদ জায়গা।
Node.js
const { GoogleGenerativeAI } = require('@google/generative-ai');
const { defineSecret } = require('firebase-functions/params');
const { onInit } = require('firebase-functions/v2/core');
const apiKey = defineSecret('GOOGLE_API_KEY');
let genAI;
onInit(() => {
genAI = new GoogleGenerativeAI(apiKey.value());
})
Python
from firebase_functions.core import init
from firebase_functions.params import StringParam, PROJECT_ID
import firebase_admin
import vertexai
location = StringParam("LOCATION")
x = "hello"
@init
def initialize():
# Note: to write back to a global, you'll need to use the "global" keyword
# to avoid creating a new local with the same name.
global x
x = "world"
firebase_admin.initialize_app()
vertexai.init(PROJECT_ID.value, location.value)
আপনি Secret ধরনের প্যারামিটার ব্যবহার করলে, মনে রাখবেন যে সেগুলি শুধুমাত্র
সেইসব ফাংশনের প্রসেসে উপলভ্য যেগুলি সিক্রেটকে বাইন্ড করেছে। কোনও সিক্রেট যদি
শুধুমাত্র কিছু ফাংশনে আবদ্ধ থাকে, তাহলে এটি ব্যবহার করার আগে secret.value() মিথ্যা কিনা তা চেক করুন।
CLI-এর আচরণ কনফিগার করা
Options অবজেক্টের সাহায্যে প্যারামিটার কনফিগার করা যায়, এটি কীভাবে CLI
মান প্রম্পট করবে তা নিয়ন্ত্রণ করে। নিচের উদাহরণে ফোন নম্বরের
ফর্ম্যাট যাচাই করার, একটি সহজ বেছে নেওয়ার বিকল্প প্রদান করার এবং Firebase প্রোজেক্ট থেকে
বেছে নেওয়ার বিকল্প অটোমেটিক পূরণ করার বিকল্প সেট করা হয়েছে:
Node.js
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});
const onlyPhoneNumbers = defineString('PHONE_NUMBER', {
input: {
text: {
validationRegex: /\d{3}-\d{3}-\d{4}/,
validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"
},
},
});
const selectedOption = defineString('PARITY', {input: params.select(["odd", "even"])});
const memory = defineInt("MEMORY", {
description: "How much memory do you need?",
input: params.select({ "micro": 256, "chonky": 2048 }),
});
const extensions = defineList("EXTENSIONS", {
description: "Which file types should be processed?",
input: params.multiSelect(["jpg", "tiff", "png", "webp"]),
});
const storageBucket = defineString('BUCKET', {
description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets",
input: params.PICK_STORAGE_BUCKET,
});
Python
from firebase_functions.params import (
StringParam,
ListParam,
TextInput,
SelectInput,
SelectOptions,
ResourceInput,
ResourceType,
)
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam(
"WELCOME_MESSAGE",
default="Hello World",
description="The greeting that is returned to the caller of this function",
)
ONLY_PHONE_NUMBERS = StringParam(
"PHONE_NUMBER",
input=TextInput(
validation_regex="\d{3}-\d{3}-\d{4}",
validation_error_message="Please enter a phone number in the format XXX-YYY-XXX",
),
)
SELECT_OPTION = StringParam(
"PARITY",
input=SelectInput([SelectOptions(value="odd"), SelectOptions(value="even")]),
)
STORAGE_BUCKET = StringParam(
"BUCKET",
input=ResourceInput(type=ResourceType.STORAGE_BUCKET),
description="This will automatically populate the selector field with the deploying Cloud Project's storage buckets",
)
প্যারামিটারের ধরন
প্যারামিটারাইজড কনফিগারেশন প্যারামিটার ভ্যালুর জন্য শক্তিশালী টাইপিং প্রদান করে এবং Cloud Secret Manager থেকে সিক্রেটও সাপোর্ট করে। এইসব ধরন কাজ করে:
- রহস্য
- স্ট্রিং
- Boolean
- পূর্ণসংখ্যা
- ফ্লোট
- তালিকা (Node.js)
- JSON সিক্রেট (Node.js)
প্যারামিটার নির্ধারণ করার ফাংশন সম্পর্কে তথ্য পেতে, params নেমস্পেস রেফারেন্স
দেখুন।
প্যারামিটার ভ্যালু ও এক্সপ্রেশন
Firebase আপনার প্যারামিটারগুলি ডিপ্লয় করার সময় এবং আপনার ফাংশন এক্সিকিউট করার সময় মূল্যায়ন করে। এইসব দ্বৈত এনভায়রনমেন্টের কারণে, প্যারামিটার ভ্যালু তুলনা করার সময় এবং আপনার ফাংশনের জন্য রানটাইম বিকল্প সেট করার সময় অতিরিক্ত সতর্কতা অবলম্বন করতে হবে।
রানটাইম বিকল্প হিসেবে আপনার ফাংশনে প্যারামিটার পাস করতে, এটি সরাসরি পাস করুন:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineInt } = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
এছাড়াও, কোন বিকল্প বেছে নিতে হবে তা জানতে কোনও প্যারামিটারের সাথে তুলনা করার প্রয়োজন হলে, আপনাকে ভ্যালু চেক করার পরিবর্তে বিল্ট-ইন তুলনাকারী ব্যবহার করতে হবে:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const environment = params.defineString(‘ENVIRONMENT’, {default: 'dev'});
// use built-in comparators
const minInstancesConfig = environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
ENVIRONMENT = StringParam("ENVIRONMENT", default="dev")
MIN_INSTANCES = ENVIRONMENT.equals("PRODUCTION").then(10, 0)
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
রানটাইমে শুধুমাত্র ব্যবহৃত প্যারামিটার ও প্যারামিটার এক্সপ্রেশনকে সেগুলির value ফাংশনের মাধ্যমে অ্যাক্সেস করা
যায়:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');
// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = onRequest(
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python
from firebase_functions import https_fn
from firebase_functions.params import StringParam
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
@https_fn.on_request()
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')
বিল্ট-ইন প্যারামিটার
Cloud Functions SDK-তে তিনটি পূর্ব-নির্ধারিত প্যারামিটার আছে, যা firebase-functions/params সাবপ্যাকেজ থেকে
উপলভ্য:
Node.js
projectID— ফাংশনটি যে Cloud প্রোজেক্টে চলছে।databaseURL— ফাংশনের সাথে যুক্ত Realtime Database ইনস্ট্যান্সের URL (Firebase প্রোজেক্টে চালু করা থাকলে)।storageBucket— ফাংশনের সাথে যুক্ত Cloud Storage বাকেট (Firebase প্রোজেক্টে চালু থাকলে)।
Python
PROJECT_ID— ফাংশনটি যে Cloud প্রোজেক্টে চলছে।DATABASE_URL— ফাংশনের সাথে যুক্ত Realtime Database ইনস্ট্যান্সের URL (Firebase প্রোজেক্টে চালু করা থাকলে)।STORAGE_BUCKET— ফাংশনের সাথে যুক্ত Cloud Storage বাকেট (Firebase প্রোজেক্টে চালু থাকলে)।
এইসব ফাংশন সব দিক থেকে ব্যবহারকারী-সংজ্ঞায়িত স্ট্রিং
প্যারামিটারের মতো, শুধু পার্থক্য হল, Firebase CLI সবসময় এদের ভ্যালু জানে বলে, এদের ভ্যালু
ডিপ্লয়মেন্টের সময় প্রম্পট করা হবে না এবং .env ফাইলে সেভ করা হবে না।
গোপন প্যারামিটার
defineSecret() ব্যবহার করে সংজ্ঞায়িত Secret ধরনের প্যারামিটার, Cloud Secret Manager-এ সেভ করা মান সহ স্ট্রিং
প্যারামিটারকে বোঝায়। লোকাল .env ফাইলের সাথে চেক করা এবং
সেটি না থাকলে নতুন ভ্যালু লেখার পরিবর্তে, সিক্রেট প্যারামিটার Cloud Secret Manager-এ আছে কিনা তা চেক করে এবং
ডেপ্লয়মেন্টের সময় নতুন সিক্রেটের ভ্যালু ইন্ট্যার্যাক্টিভভাবে প্রম্পট করে।
সিক্রেট প্যারামিটার অবশ্যই সেইসব স্বতন্ত্র ফাংশনের সাথে যুক্ত থাকতে হবে যেগুলির সেগুলিতে অ্যাক্সেস থাকা উচিত:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');
export const postToDiscord = onRequest(
{ secrets: [discordApiKey] },
(req, res) => {
const apiKey = discordApiKey.value();
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import SecretParam
DISCORD_API_KEY = SecretParam('DISCORD_API_KEY')
@https_fn.on_request(secrets=[DISCORD_API_KEY])
def post_to_discord(req):
api_key = DISCORD_API_KEY.value
ফাংশন এক্সিকিউট না হওয়া পর্যন্ত সিক্রেটের ভ্যালু লুকানো থাকে বলে, আপনি ফাংশন কনফিগার করার সময় সেগুলি ব্যবহার করতে পারবেন না।
স্ট্রাকচার্ড JSON সিক্রেট
আপনার কাছে যদি একাধিক কনফিগারেশন ভ্যালু থাকে যেগুলি যৌক্তিকভাবে সম্পর্কিত (যেমন, থার্ড-পার্টি পরিষেবার জন্য সেটিংস), তাহলে আপনি সেগুলিকে defineJsonSecret() ব্যবহার করে একটি সিক্রেটের মধ্যে
স্ট্রাকচার্ড JSON অবজেক্ট হিসেবে একসাথে স্টোর করতে পারবেন। এই
পদ্ধতি আপনার কনফিগারেশন সাজাতে এবং একটি সিক্রেটে সম্পর্কিত কনফিগারেশন
ভ্যালুর একটি গ্রুপ স্টোর করে Cloud Secret Manager-এর
ফ্রি টিয়ার আরও দক্ষতার সাথে ব্যবহার করতে সাহায্য করতে পারে।
Secret Manager-এ সেভ করা ভ্যালু সঠিক JSON স্ট্রিং হতে হবে। আপনি .value() অ্যাক্সেস করলে SDK অটোমেটিক JSON স্ট্রিং পার্স করে JavaScript অবজেক্টে পরিবর্তন করবে।
উদাহরণ:
const { onRequest } = require('firebase-functions/v2/https');
const { defineJsonSecret } = require('firebase-functions/params');
// Define a single secret to hold all configuration for some API
const someApiConfig = defineJsonSecret('SOMEAPI_CONFIG');
exports.myApi = onRequest(
{ secrets: [someApiConfig] },
(req, res) => {
// someApiConfig.value() automatically parses the JSON secret
const { apiKey, webhookSecret, clientId } = someApiConfig.value();
// Now you can use apiKey, webhookSecret, clientId
// ...
}
);
SOMEAPI_CONFIG গোপন তথ্য তৈরি করতে, Secret Manager-এ এর মান JSON স্ট্রিং হিসেবে সেট করুন, যেমন:
{
"apiKey": "key_...",
"webhookSecret": "secret_...",
"clientId": "client_..."
}
গোপন মানটি সঠিক JSON না হলে, someApiConfig.value() অ্যাক্সেস করার সময় রানটাইমে একটি সমস্যা হবে।
এনভায়রনমেন্ট ভেরিয়েবল
Cloud Functions for Firebase আপনার
অ্যাপ্লিকেশন রানটাইমে .env ফাইলে নির্দিষ্ট করা এনভায়রনমেন্ট ভেরিয়েবেল লোড করার জন্য
dotenv
ফাইল ফর্ম্যাট ব্যবহার করে। ডেপ্লয় করা হয়ে গেলে, এনভায়রনমেন্ট ভেরিয়েবলকে
process.env
ইন্টারফেসের (Node.js-ভিত্তিক প্রোজেক্টে) মাধ্যমে অথবা
os.environ (Python-ভিত্তিক প্রোজেক্টে) থেকে
পড়া যেতে পারে।
এইভাবে আপনার এনভায়রনমেন্ট কনফিগার করতে, আপনার প্রোজেক্টে একটি .env ফাইল তৈরি করুন,
পছন্দসই ভেরিয়েবল যোগ করুন এবং ডেপ্লয় করুন:
আপনার
functions/ডিরেক্টরিতে একটি.envফাইল তৈরি করুন:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.jsএডিট করার জন্য
.envফাইল খুলুন এবং পছন্দসই কী যোগ করুন। যেমন:PLANET=Earth AUDIENCE=Humansফাংশন ডেপ্লয় করুন এবং এনভায়রনমেন্ট ভেরিয়েবল লোড করা হয়েছে কিনা তা যাচাই করুন:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
আপনার কাস্টম এনভায়রনমেন্ট ভেরিয়েবল ডেপ্লয় করা হয়ে গেলে, আপনার ফাংশন কোড সেগুলি অ্যাক্সেস করতে পারবে:
Node.js
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
Python
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
)
একাধিক সেট এনভায়রনমেন্ট ভেরিয়েবল ডেপ্লয় করা
আপনার Firebase
প্রোজেক্টের জন্য বিকল্প এনভায়রনমেন্ট ভেরিয়েবল (যেমন, স্টেজিং বনাম প্রোডাকশন) প্রয়োজন হলে, একটি
.env.<project or
alias> ফাইল তৈরি করুন এবং আপনার
প্রোজেক্ট-নির্দিষ্ট এনভায়রনমেন্ট ভেরিয়েবল সেখানে লিখুন। .env থেকে এনভায়রনমেন্ট ভেরিয়েবল এবং প্রোজেক্ট-নির্দিষ্ট .env ফাইল (যদি থাকে)
সব ডিপ্লয় করা ফাংশনে অন্তর্ভুক্ত করা হবে।
যেমন, কোনও প্রোজেক্টে ডেভেলপমেন্ট ও প্রোডাকশনের জন্য সামান্য আলাদা ভ্যালু সহ এই তিনটি ফাইল থাকতে পারে:
.env
|
.env.dev
|
.env.prod
|
| PLANET=পৃথিবী
AUDIENCE=মানুষ |
AUDIENCE=Dev Humans | AUDIENCE=Prod Humans |
সেইসব আলাদা ফাইলে দেওয়া ভ্যালু অনুযায়ী, আপনার ফাংশনের সাথে ডিপ্লয় করা এনভায়রনমেন্ট ভেরিয়েবলের সেট আপনার টার্গেট প্রোজেক্টের উপর নির্ভর করে আলাদা আলাদা হবে:
$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
# PLANET=Earth
# AUDIENCE=Dev Humans
$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
# PLANET=Earth
# AUDIENCE=Prod Humans
রিজার্ভ করা এনভায়রনমেন্ট ভেরিয়েবল
কিছু এনভায়রনমেন্ট ভেরিয়েবল কী ইন্টার্নাল ব্যবহারের জন্য রিজার্ভ করা থাকে। আপনার .env ফাইলে এইসব কী
ব্যবহার করবেন না:
- X_GOOGLE_ দিয়ে শুরু হওয়া সব কী
- EXT_ দিয়ে শুরু হওয়া সব কী
- FIREBASE_ দিয়ে শুরু হওয়া সব কী
- নিম্নলিখিত তালিকার যেকোনও কী:
- CLOUD_RUNTIME_CONFIG
- ENTRY_POINT
- GCP_PROJECT
- GCLOUD_PROJECT
- GOOGLE_CLOUD_PROJECT
- FUNCTION_TRIGGER_TYPE
- FUNCTION_NAME
- FUNCTION_MEMORY_MB
- FUNCTION_TIMEOUT_SEC
- FUNCTION_IDENTITY
- FUNCTION_REGION
- FUNCTION_TARGET
- FUNCTION_SIGNATURE_TYPE
- K_SERVICE
- K_REVISION
- PORT
- K_CONFIGURATION
সংবেদনশীল কনফিগারেশন সংক্রান্ত তথ্য স্টোর ও অ্যাক্সেস করা
.env ফাইলে সেভ করা এনভায়রনমেন্ট ভেরিয়েবল ফাংশন
কনফিগারেশনের জন্য ব্যবহার করা যেতে পারে, তবে ডেটাবেস ক্রেডেনশিয়াল বা API কী-এর মতো সংবেদনশীল
তথ্য সেভ করার জন্য এগুলিকে নিরাপদ উপায় হিসেবে বিবেচনা করা উচিত নয়। আপনি সোর্স কন্ট্রোলে নিজের .env ফাইল চেক করলে এটি বিশেষভাবে
গুরুত্বপূর্ণ।
সংবেদনশীল কনফিগারেশন সংক্রান্ত তথ্য স্টোর করতে সাহায্য করতে, Cloud Functions for Firebase Google Cloud Secret Manager-এর সাথে ইন্টিগ্রেট করে। এই এনক্রিপ্টেড পরিষেবা নিরাপদে কনফিগারেশন ভ্যালু স্টোর করে, তবে প্রয়োজন হলে আপনার ফাংশন থেকে সহজে অ্যাক্সেস করার অনুমতি দেয়।
একটি সিক্রেট তৈরি ও ব্যবহার করা
সিক্রেট তৈরি করতে, Firebase CLI ব্যবহার করুন।
সিক্রেট তৈরি ও ব্যবহার করতে:
আপনার স্থানীয় প্রোজেক্ট ডিরেক্টরির রুট থেকে, নিম্নলিখিত কমান্ড রান করুন:
firebase functions:secrets:set SECRET_NAME
SECRET_NAME-এর জন্য একটি মান লিখুন।
CLI একটি সফলতার মেসেজ দেখায় এবং সতর্ক করে যে পরিবর্তন কার্যকর করতে আপনাকে ফাংশন ডেপ্লয় করতে হবে।
ডেপ্লয় করার আগে, আপনার ফাংশন কোড
secretsবিকল্প ব্যবহার করে ফাংশনকে সিক্রেট অ্যাক্সেস করতে দেয় কিনা তা নিশ্চিত করুন:Node.js
const { onRequest } = require('firebase-functions/v2/https'); exports.processPayment = onRequest( { secrets: ["SECRET_NAME"] }, (req, res) => { const myBillingService = initializeBillingService( // reference the secret value process.env.SECRET_NAME ); // Process the payment } );Python
import os from firebase_functions import https_fn @https_fn.on_request(secrets=["SECRET_NAME"]) def process_payment(req): myBillingService = initialize_billing(key=os.environ.get('SECRET_NAME')) # Process the payment ...ডিপ্লয় করুন Cloud Functions:
firebase deploy --only functions
এখন আপনি অন্য যেকোনও এনভায়রনমেন্ট ভেরিয়েবলের মতো এটি অ্যাক্সেস করতে পারবেন। অন্যদিকে, অন্য কোনও ফাংশন যদি গোপন মান উল্লেখ না করে সেটি অ্যাক্সেস করার চেষ্টা করে, তাহলে সেটি একটি অনির্দিষ্ট মান পায়:
Node.js
exports.anotherEndpoint = onRequest((request, response) => { response.send(`The secret API key is ${process.env.SECRET_NAME}`); // responds with "The secret API key is undefined" because the `secrets` option is missing });Python
@https_fn.on_request() def another_endpoint(req): return https_fn.Response(f"The secret API key is {os.environ.get("SECRET_NAME")}") # Responds with "The secret API key is None" because the `secrets` parameter is missing.
আপনার ফাংশন ডেপ্লয় করা হয়ে গেলে, এটি সিক্রেট ভ্যালু অ্যাক্সেস করতে পারবে। শুধুমাত্র
সেইসব ফাংশন যেগুলির secrets বিকল্পে বিশেষভাবে কোনও সিক্রেট অন্তর্ভুক্ত করা আছে, সেগুলিই
এনভায়রনমেন্ট ভেরিয়েবল হিসেবে সেই সিক্রেট অ্যাক্সেস করতে পারবে। এটি আপনাকে নিশ্চিত করতে সাহায্য করে যে
গোপন ভ্যালু শুধুমাত্র যেখানে প্রয়োজন সেখানেই উপলভ্য, এর ফলে
দুর্ঘটনাক্রমে গোপন তথ্য ফাঁস হওয়ার ঝুঁকি কমে যায়।
গোপনীয় তথ্য ম্যানেজ করা
আপনার সিক্রেট ম্যানেজ করতে Firebase CLI ব্যবহার করুন। এইভাবে সিক্রেট ম্যানেজ করার সময়, মনে রাখবেন যে কিছু CLI পরিবর্তনের জন্য আপনাকে সংশ্লিষ্ট ফাংশন পরিবর্তন এবং/অথবা আবার ডিপ্লয় করতে হবে। বিশেষত:
- আপনি কোনও সিক্রেটের জন্য নতুন ভ্যালু সেট করলে, সেই সিক্রেটকে রেফারেন্স করে এমন সব ফাংশনকে আপনাকে আবার ডিপ্লয় করতে হবে, যাতে সেগুলি লেটেস্ট ভ্যালু নিতে পারে।
- আপনি কোনও সিক্রেট মুছে দিলে, আপনার ডিপ্লয় করা কোনও ফাংশন যেন সেই সিক্রেটকে রেফারেন্স না করে তা নিশ্চিত করুন। যেসব ফাংশন মুছে ফেলা হয়েছে এমন গোপন মান ব্যবহার করে সেগুলি কোনও মেসেজ না দেখিয়েই কাজ করা বন্ধ করে দেবে।
Firebase সিক্রেট ম্যানেজমেন্টের জন্য CLI কমান্ডের সারসংক্ষেপ এখানে দেওয়া হল:
# Change the value of an existing secret firebase functions:secrets:set SECRET_NAME # Set secret from file firebase functions:secrets:set SECRET_NAME --data-file file.json # Validate secret value as json cat file.json | firebase functions:secrets:set SECRET_NAME --format=json # Pipe from stdin and set secret cat file.json | firebase functions:secrets:set SECRET_NAME --format=json # View the value of a secret functions:secrets:access SECRET_NAME # Destroy a secret functions:secrets:destroy SECRET_NAME # View all secret versions and their state functions:secrets:get SECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
access এবং destroy কমান্ডের জন্য, আপনি কোনও নির্দিষ্ট ভার্সন ম্যানেজ করতে ঐচ্ছিক ভার্সন
প্যারামিটার প্রদান করতে পারেন। যেমন:
functions:secrets:access SECRET_NAME[@VERSION]
এইসব অপারেশন সম্পর্কে আরও তথ্য পেতে, CLI সহায়তা দেখতে কমান্ডের সাথে -h পাস করুন।
সিক্রেট কীভাবে বিল করা হয়
Secret Manager ৬টি অ্যাক্টিভ সিক্রেট ভার্সন ফ্রিতে ব্যবহার করার অনুমতি দেয়। এর অর্থ হল, আপনি Firebase প্রোজেক্টে প্রতি মাসে ৬টি সিক্রেট ফ্রিতে ব্যবহার করতে পারবেন।
ডিফল্ট হিসেবে, Firebase CLI উপযুক্ত জায়গায় অব্যবহৃত সিক্রেট
ভার্সন অটোমেটিক ধ্বংস করার চেষ্টা করে, যেমন আপনি সিক্রেটের নতুন ভার্সন
দিয়ে ফাংশন ডেপ্লয় করলে। এছাড়াও, আপনি
functions:secrets:destroy এবং functions:secrets:prune ব্যবহার করে অব্যবহৃত সিক্রেট অ্যাক্টিভভাবে ক্লিন-আপ করতে পারবেন।
Secret Manager একটি সিক্রেটে ১০,০০০টি আনবিল্ড মাসিক অ্যাক্সেস অপারেশন করার অনুমতি দেয়। ফাংশন ইনস্ট্যান্স প্রতিবার কোল্ড স্টার্ট করার সময় শুধুমাত্র তার secrets
বিকল্পে উল্লেখ করা সিক্রেট পড়ে। আপনার কাছে যদি অনেক ফাংশন ইনস্ট্যান্স থাকে
যেগুলি অনেক সিক্রেট রিড করছে, তাহলে আপনার প্রোজেক্ট এই অনুমোদিত সীমা অতিক্রম করতে পারে, সেই ক্ষেত্রে
প্রতি ১০,০০০ অ্যাক্সেস অপারেশনের জন্য আপনাকে $০.০৩ চার্জ করা হবে।
আরও তথ্যের জন্য, Secret Manager দাম দেখুন।
ইমুলেটর সাপোর্ট
dotenv-এর সাথে এনভায়রনমেন্ট কনফিগারেশনকে লোকাল Cloud Functions এমুলেটর-এর সাথে ইন্টারঅপারেট করার জন্য ডিজাইন করা হয়েছে।
লোকাল Cloud Functions এমুলেটর ব্যবহার করার সময়, আপনি .env.local ফাইল সেট-আপ করে আপনার প্রোজেক্টের জন্য এনভায়রনমেন্ট
ভেরিয়েবল ওভাররাইড করতে পারবেন। .env.local-এর কন্টেন্ট
.env ও প্রোজেক্ট-নির্দিষ্ট .env ফাইলের চেয়ে বেশি অগ্রাধিকার পায়।
যেমন, কোনও প্রোজেক্টে ডেভেলপমেন্ট ও লোকাল টেস্টিংয়ের জন্য সামান্য আলাদা ভ্যালু সহ এই তিনটি ফাইল থাকতে পারে:
.env
|
.env.dev
|
.env.local
|
| PLANET=পৃথিবী
AUDIENCE=মানুষ |
AUDIENCE=Dev Humans | AUDIENCE=Local Humans |
লোকাল কনটেক্সটে শুরু করলে, এমুলেটর নিম্নলিখিত এনভায়রনমেন্ট ভেরিয়েবল লোড করে:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Cloud Functions এমুলেটরে গোপনীয় তথ্য ও ক্রেডেনশিয়াল
Cloud Functions এমুলেটর সংবেদনশীল কনফিগারেশন সংক্রান্ত তথ্য সেভ ও অ্যাক্সেস করার জন্য সিক্রেট ব্যবহারের সুবিধা দেয়। ডিফল্ট হিসেবে, এমুলেটর আপনার প্রোডাকশন সিক্রেট অ্যাক্সেস করার চেষ্টা করবে, এর জন্য অ্যাপ্লিকেশনের ডিফল্ট ক্রেডেনশিয়াল ব্যবহার করা হবে। CI এনভায়রনমেন্টের মতো নির্দিষ্ট কিছু পরিস্থিতিতে, অনুমতির বিধিনিষেধের কারণে এমুলেটর হয়ত সিক্রেট ভ্যালু অ্যাক্সেস করতে পারবে না।
এনভায়রনমেন্ট ভেরিয়েবলের জন্য Cloud Functions এমুলেটর সহায়তার মতো, আপনি .secret.local ফাইল সেট-আপ করে সিক্রেট ভ্যালু
ওভাররাইড করতে পারবেন। এর ফলে, আপনি লোকালি নিজের ফাংশন সহজে পরীক্ষা করতে পারেন, বিশেষ করে আপনার কাছে সিক্রেট ভ্যালু
না থাকলে।
রানটাইম কনফিগারেশন থেকে মাইগ্রেট করা
functions.config API বন্ধ করে দেওয়া হয়েছে এবং মার্চ ২০২৭-এ এটি সরিয়ে দেওয়া হবে।
ওই তারিখের পরে, functions.config সহ ডেপ্লয়মেন্ট কাজ করবে না।
ডিপ্লয়মেন্ট ব্যর্থতা আটকাতে, Firebase CLI ব্যবহার করে আপনার কনফিগারেশন Cloud Secret Manager-এ মাইগ্রেট করুন। এটি সাজেস্ট করা হয় কারণ আপনার কনফিগারেশন মাইগ্রেট করার সবচেয়ে সুরক্ষিত ও কার্যকর উপায় এটি।
Firebase CLI-এর মাধ্যমে কনফিগারেশন এক্সপোর্ট করা
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>
অটোমেটিক পূরণ হওয়া এনভায়রনমেন্ট ভেরিয়েবল
ফাংশন রানটাইম এবং লোকালি এমুলেট করা ফাংশনে অটোমেটিক পপুলেট করা এনভায়রনমেন্ট ভেরিয়েবল থাকে। এর মধ্যে Google Cloud-এর দ্বারা অটোমেটিক পূরণ করা ভেরিয়েবল এবং Firebase-নির্দিষ্ট এনভায়রনমেন্ট ভেরিয়েবল অন্তর্ভুক্ত:
process.env.FIREBASE_CONFIG: Firebase প্রোজেক্ট কনফিগারেশন সংক্রান্ত নিম্নলিখিত তথ্য প্রদান করে:
{
databaseURL: 'https://DATABASE_NAME.firebaseio.com',
storageBucket: 'PROJECT_ID.firebasestorage.app ',
projectId: 'PROJECT_ID'
}
মনে রাখবেন, আপনার আসল Firebase কনফিগারেশনের ভ্যালু আপনার প্রোজেক্টে প্রোভিশন করা রিসোর্সের উপর নির্ভর করে আলাদা হতে পারে।
আপনি কোনও আর্গুমেন্ট ছাড়াই Firebase Admin SDK শুরু করলে এই কনফিগারেশন অটোমেটিক প্রয়োগ করা হয়। আপনি JavaScript-এ ফাংশন লিখলে, এইভাবে ইনিশিয়ালাইজ করুন:
const admin = require('firebase-admin');
admin.initializeApp();
আপনি TypeScript-এ ফাংশন লিখলে, এইভাবে ইনিশিয়ালাইজ করুন:
import * as functions from 'firebase-functions/v1';
import * as admin from 'firebase-admin';
import 'firebase-functions/v1';
admin.initializeApp();
আপনি যদি পরিষেবা অ্যাকাউন্টের ক্রেডেনশিয়াল ব্যবহার করে ডিফল্ট প্রোজেক্ট কনফিগারেশনের
সাথে Admin SDK ইনিশিয়ালাইজ করতে চান, তাহলে আপনি কোনও ফাইল থেকে ক্রেডেনশিয়াল লোড করতে এবং
FIREBASE_CONFIG-এ এইভাবে যোগ করতে পারেন:
serviceAccount = require('./serviceAccount.json');
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);