আপনার পরিবেশ কনফিগার করুন

প্রায়শই আপনার ফাংশনগুলির জন্য অতিরিক্ত কনফিগারেশনের প্রয়োজন হবে, যেমন থার্ড-পার্টি এপিআই কী বা পরিবর্তনযোগ্য সেটিংস। Cloud Functions জন্য Firebase এসডিকে-তে বিল্ট-ইন এনভায়রনমেন্ট কনফিগারেশন রয়েছে, যা আপনার প্রোজেক্টের জন্য এই ধরনের ডেটা সংরক্ষণ এবং পুনরুদ্ধার করা সহজ করে তোলে।

আপনি এই বিকল্পগুলো থেকে বেছে নিতে পারেন:

  • প্যারামিটারযুক্ত কনফিগারেশন (অধিকাংশ ক্ষেত্রে এটিই সুপারিশ করা হয়)। এটি এমন প্যারামিটারসহ স্ট্রংলি-টাইপড এনভায়রনমেন্ট কনফিগারেশন প্রদান করে, যা ডিপ্লয় করার সময় যাচাই করা হয়। এর ফলে ত্রুটি প্রতিরোধ করা যায় এবং ডিবাগিং সহজ হয়।
  • এনভায়রনমেন্ট ভেরিয়েবলের ফাইল-ভিত্তিক কনফিগারেশন। এই পদ্ধতিতে, এনভায়রনমেন্ট ভেরিয়েবল লোড করার জন্য আপনাকে ম্যানুয়ালি একটি ডটএনভ (dotenv) ফাইল তৈরি করতে হয়।

বেশিরভাগ ক্ষেত্রে প্যারামিটারযুক্ত কনফিগারেশন ব্যবহার করার পরামর্শ দেওয়া হয়। এই পদ্ধতিতে কনফিগারেশনের মানগুলো রানটাইম এবং ডিপ্লয় টাইম উভয় সময়েই পাওয়া যায়, এবং সব প্যারামিটারের মান বৈধ না হলে ডিপ্লয়মেন্ট আটকে থাকে। অন্যদিকে, এনভায়রনমেন্ট ভেরিয়েবল দিয়ে করা কনফিগারেশন ডিপ্লয় টাইমে পাওয়া যায় না।

প্যারামিটারযুক্ত কনফিগারেশন

Cloud Functions for Firebase আপনার কোডবেসের ভিতরে ডিক্লারেটিভভাবে কনফিগারেশন প্যারামিটার নির্ধারণ করার জন্য একটি ইন্টারফেস প্রদান করে। এই প্যারামিটারগুলোর মান ফাংশন ডিপ্লয়মেন্টের সময়, অর্থাৎ ডিপ্লয়মেন্ট ও রানটাইম অপশন সেট করার সময় এবং এক্সিকিউশনের সময়—সব ক্ষেত্রেই উপলব্ধ থাকে। এর মানে হলো, যতক্ষণ না সমস্ত প্যারামিটারের একটি বৈধ মান থাকবে, ততক্ষণ পর্যন্ত CLI ডিপ্লয়মেন্ট আটকে দেবে।

নোড.জেএস

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

পাইথন

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() ইনিশিয়ালাইজেশন কলব্যাকটি ব্যবহার করুন। এই কলব্যাকটি প্রোডাকশনে যেকোনো ফাংশন চলার আগে রান করে, কিন্তু ডিপ্লয়মেন্টের সময় কল করা হয় না, তাই এটি প্যারামিটারের মান অ্যাক্সেস করার জন্য একটি নিরাপদ জায়গা।

নোড.জেএস

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

পাইথন

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() ফলসি (falsy) কিনা তা যাচাই করে নিন।

CLI আচরণ কনফিগার করুন

Parameters can be configured with an Options object that controls how the CLI will prompt for values. The following example sets options to validate the format of a phone number, to provide a simple selection option, and to populate a selection option automatically from the Firebase project:

নোড.জেএস

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,
});

পাইথন

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",
)

প্যারামিটার প্রকার

প্যারামিটারাইজড কনফিগারেশন প্যারামিটার ভ্যালুগুলোর জন্য স্ট্রং টাইপিং প্রদান করে এবং ক্লাউড সিক্রেট ম্যানেজার থেকে সিক্রেটও সাপোর্ট করে। সমর্থিত টাইপগুলো হলো:

  • গোপন
  • স্ট্রিং
  • বুলিয়ান
  • পূর্ণসংখ্যা
  • ভাসা
  • তালিকা (নোড.জেএস)
  • JSON গোপন (নোড.জেএস)

প্যারামিটার নির্ধারণের ফাংশনগুলো সম্পর্কে তথ্যের জন্য params নেমস্পেস রেফারেন্স দেখুন।

প্যারামিটার মান এবং অভিব্যক্তি

ফায়ারবেস আপনার প্যারামিটারগুলো ডিপ্লয় করার সময় এবং আপনার ফাংশনটি চলার সময় উভয় ক্ষেত্রেই মূল্যায়ন করে। এই দ্বৈত পরিবেশের কারণে, প্যারামিটারের মান তুলনা করার সময় এবং আপনার ফাংশনগুলোর জন্য রানটাইম অপশন সেট করতে সেগুলো ব্যবহার করার সময় কিছু বাড়তি সতর্কতা অবলম্বন করতে হবে।

আপনার ফাংশনে রানটাইম অপশন হিসেবে কোনো প্যারামিটার পাস করতে, সেটি সরাসরি পাস করুন:

নোড.জেএস

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) => {
    //…

পাইথন

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):
    ...

এছাড়াও, কোন বিকল্পটি বেছে নিতে হবে তা জানার জন্য যদি কোনো প্যারামিটারের সাথে তুলনা করার প্রয়োজন হয়, তাহলে মানটি যাচাই করার পরিবর্তে আপনাকে বিল্ট-ইন কম্পারেটর ব্যবহার করতে হবে:

নোড.জেএস

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) => {
    //…

পাইথন

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 ফাংশনের মাধ্যমে অ্যাক্সেস করা যায়:

নোড.জেএস

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

পাইথন

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!')

অন্তর্নির্মিত পরামিতি

ক্লাউড ফাংশনস এসডিকে তিনটি পূর্ব-নির্ধারিত প্যারামিটার প্রদান করে, যা firebase-functions/params সাবপ্যাকেজ থেকে পাওয়া যায়:

নোড.জেএস

  • projectID — যে ক্লাউড প্রজেক্টে ফাংশনটি চলছে।
  • databaseURL — ফাংশনটির সাথে যুক্ত রিয়েলটাইম ডাটাবেস ইনস্ট্যান্সের URL (যদি ফায়ারবেস প্রজেক্টে এটি সক্রিয় করা থাকে)।
  • storageBucket — ফাংশনটির সাথে যুক্ত ক্লাউড স্টোরেজ বাকেট (যদি Firebase প্রজেক্টে এটি সক্রিয় করা থাকে)।

পাইথন

  • PROJECT_ID — যে ক্লাউড প্রজেক্টে ফাংশনটি চলছে।
  • DATABASE_URL — ফাংশনটির সাথে যুক্ত রিয়েলটাইম ডাটাবেস ইনস্ট্যান্সের URL (যদি ফায়ারবেস প্রজেক্টে এটি সক্রিয় করা থাকে)।
  • STORAGE_BUCKET — ফাংশনটির সাথে যুক্ত ক্লাউড স্টোরেজ বাকেট (যদি ফায়ারবেস প্রজেক্টে এটি সক্রিয় করা থাকে)।

এগুলো সব দিক থেকে ইউজার-ডিফাইন্ড স্ট্রিং প্যারামিটারের মতোই কাজ করে, তবে পার্থক্য হলো, যেহেতু এদের মান Firebase CLI-এর কাছে সবসময় জানা থাকে, তাই ডিপ্লয়মেন্টের সময় এদের মানের জন্য কখনো জিজ্ঞাসা করা হবে না বা এগুলো .env ফাইলে সেভ করা হবে না।

গোপন পরামিতি

defineSecret() ব্যবহার করে সংজ্ঞায়িত Secret টাইপের প্যারামিটারগুলো হলো এমন স্ট্রিং প্যারামিটার, যার মান ক্লাউড সিক্রেট ম্যানেজারে সংরক্ষিত থাকে। স্থানীয় .env ফাইলের সাথে মিলিয়ে দেখে এবং মানটি অনুপস্থিত থাকলে ফাইলে একটি নতুন মান লেখার পরিবর্তে, সিক্রেট প্যারামিটারগুলো ক্লাউড সিক্রেট ম্যানেজারে এর অস্তিত্ব যাচাই করে এবং ডেপ্লয়মেন্টের সময় একটি নতুন সিক্রেটের মানের জন্য ইন্টারেক্টিভভাবে অনুরোধ জানায়।

গোপন প্যারামিটারগুলোকে অবশ্যই সেইসব স্বতন্ত্র ফাংশনের সাথে আবদ্ধ করতে হবে, যেগুলোর সেগুলোতে অ্যাক্সেস থাকা উচিত:

নোড.জেএস

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

পাইথন

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 অবজেক্ট হিসেবে একসাথে সংরক্ষণ করতে পারেন। এই পদ্ধতিটি আপনার কনফিগারেশনকে সুসংগঠিত করতে এবং সম্পর্কিত কনফিগারেশন ভ্যালুগুলোর একটি গ্রুপকে একটিমাত্র সিক্রেটে সংরক্ষণ করার মাধ্যমে ক্লাউড সিক্রেট ম্যানেজার ফ্রি টিয়ারের আরও কার্যকর ব্যবহারে সহায়তা করতে পারে।

সিক্রেট ম্যানেজারে সংরক্ষিত মানটি অবশ্যই একটি বৈধ JSON স্ট্রিং হতে হবে। আপনি যখন .value() অ্যাক্সেস করবেন, SDK স্বয়ংক্রিয়ভাবে JSON স্ট্রিংটিকে একটি জাভাস্ক্রিপ্ট অবজেক্টে পার্স করবে।

উদাহরণ:

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 সিক্রেটটি তৈরি করতে, আপনাকে সিক্রেট ম্যানেজারে এর মানটি নিম্নরূপ একটি JSON স্ট্রিং-এ সেট করতে হবে:

{
  "apiKey": "key_...",
  "webhookSecret": "secret_...",
  "clientId": "client_..."
}

যদি সিক্রেট ভ্যালুটি বৈধ JSON না হয়, তাহলে রানটাইমে someApiConfig.value() অ্যাক্সেস করলে একটি এরর দেখা দেবে।

পরিবেশগত পরিবর্তনশীল

Cloud Functions for Firebase supports the dotenv file format for loading environment variables specified in a .env file to your application runtime. Once deployed, the environment variables can be read via the process.env interface (in Node.js-based projects) or os.environ (in Python-based projects).

আপনার এনভায়রনমেন্ট এইভাবে কনফিগার করতে, আপনার প্রোজেক্টে একটি .env ফাইল তৈরি করুন, প্রয়োজনীয় ভ্যারিয়েবলগুলো যোগ করুন এবং ডিপ্লয় করুন:

  1. আপনার functions/ ডিরেক্টরিতে একটি .env ফাইল তৈরি করুন:

    # Directory layout:
    #   my-project/
    #     firebase.json
    #     functions/
    #       .env
    #       package.json
    #       index.js
    
  2. সম্পাদনার জন্য .env ফাইলটি খুলুন এবং প্রয়োজনীয় কী-গুলো যোগ করুন। উদাহরণস্বরূপ:

    PLANET=Earth
    AUDIENCE=Humans
    
  3. ফাংশনগুলো স্থাপন করুন এবং পরিবেশ ভেরিয়েবলগুলো লোড হয়েছে কিনা তা যাচাই করুন:

    firebase deploy --only functions
    # ...
    # i functions: Loaded environment variables from .env.
    # ...
    

একবার আপনার কাস্টম এনভায়রনমেন্ট ভেরিয়েবলগুলো ডেপ্লয় করা হয়ে গেলে, আপনার ফাংশন কোড সেগুলো অ্যাক্সেস করতে পারবে:

নোড.জেএস

// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
  response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});

পাইথন

import os

@https_fn.on_request()
def hello(req):
    return https_fn.Response(
        f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
    )

একাধিক পরিবেশ ভেরিয়েবল সেট স্থাপন করা

If you need an alternative set of environment variables for your Firebase projects (such as staging vs production), create a .env. <project or alias > file and write your project-specific environment variables there. The environment variables from .env and project-specific .env files (if they exist) will be included in all deployed functions.

উদাহরণস্বরূপ, একটি প্রকল্পে এই তিনটি ফাইল অন্তর্ভুক্ত থাকতে পারে, যেগুলিতে ডেভেলপমেন্ট এবং প্রোডাকশনের জন্য মানগুলো সামান্য ভিন্ন:

.env .env.dev .env.prod
গ্রহ=পৃথিবী

দর্শক = মানুষ

দর্শক = ডেভ মানুষ দর্শক = পেশাদার মানুষ

ওই আলাদা ফাইলগুলোর মান অনুযায়ী, আপনার ফাংশনগুলোর সাথে ব্যবহৃত এনভায়রনমেন্ট ভেরিয়েবলের সেট আপনার টার্গেট প্রজেক্টের ওপর নির্ভর করে ভিন্ন হবে:

$ 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_ দিয়ে শুরু হওয়া সমস্ত কী
  • নিম্নলিখিত তালিকা থেকে যেকোনো কী:
  • ক্লাউড_রানটাইম_কনফিগ
  • প্রবেশ বিন্দু
  • জিসিপি_প্রজেক্ট
  • জিক্লাউড_প্রজেক্ট
  • গুগল_ক্লাউড_প্রজেক্ট
  • ফাংশন_ট্রিগার_টাইপ
  • ফাংশনের নাম
  • ফাংশন_মেমরি_এমবি
  • ফাংশন_টাইমআউট_সেকেন্ড
  • ফাংশন_আইডেন্টিটি
  • ফাংশন_অঞ্চল
  • ফাংশন_টার্গেট
  • ফাংশন_স্বাক্ষর_প্রকার
  • কে_সার্ভিস
  • কে_রিভিশন
  • বন্দর
  • কে_কনফিগারেশন

সংবেদনশীল কনফিগারেশন তথ্য সংরক্ষণ এবং অ্যাক্সেস করুন

.env ফাইলে সংরক্ষিত এনভায়রনমেন্ট ভেরিয়েবল ফাংশন কনফিগারেশনের জন্য ব্যবহার করা যেতে পারে, কিন্তু ডাটাবেস ক্রেডেনশিয়াল বা এপিআই কী-এর মতো সংবেদনশীল তথ্য সংরক্ষণের জন্য এগুলোকে একটি নিরাপদ উপায় হিসেবে বিবেচনা করা উচিত নয়। আপনি যদি আপনার .env ফাইলগুলো সোর্স কন্ট্রোলে চেক ইন করেন, তবে এই বিষয়টি বিশেষভাবে গুরুত্বপূর্ণ।

সংবেদনশীল কনফিগারেশন তথ্য সংরক্ষণে আপনাকে সাহায্য করার জন্য, Cloud Functions for Firebase Google Cloud Secret Manager সাথে সমন্বিত হয়। এই এনক্রিপ্টেড পরিষেবাটি কনফিগারেশন ভ্যালুগুলোকে নিরাপদে সংরক্ষণ করে, এবং একই সাথে প্রয়োজনে আপনার ফাংশনগুলো থেকে সেগুলোতে সহজে অ্যাক্সেসের সুযোগও দেয়।

একটি গোপনীয়তা তৈরি করুন এবং ব্যবহার করুন

সিক্রেট তৈরি করতে Firebase সিএলআই ব্যবহার করুন।

একটি গোপনীয় তথ্য তৈরি ও ব্যবহার করতে:

  1. আপনার স্থানীয় প্রজেক্ট ডিরেক্টরির রুট থেকে নিম্নলিখিত কমান্ডটি চালান:

    firebase functions:secrets:set SECRET_NAME

  2. SECRET_NAME এর জন্য একটি মান লিখুন।

    CLI একটি সফলতার বার্তা প্রদর্শন করে এবং সতর্ক করে যে পরিবর্তনটি কার্যকর হওয়ার জন্য আপনাকে অবশ্যই ফাংশনগুলো ডিপ্লয় করতে হবে।

  3. ডিপ্লয় করার আগে, নিশ্চিত করুন যে আপনার ফাংশন কোড ' secrets অপশনটি ব্যবহার করে ফাংশনটিকে সিক্রেটটি অ্যাক্সেস করার অনুমতি দেয়:

    নোড.জেএস

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

    পাইথন

    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
        ...
    
  4. Cloud Functions স্থাপন করুন :

    firebase deploy --only functions

    এখন আপনি এটিকে অন্য যেকোনো এনভায়রনমেন্ট ভেরিয়েবলের মতোই অ্যাক্সেস করতে পারবেন। বিপরীতভাবে, যদি অন্য কোনো ফাংশন, যা সিক্রেটটি নির্দিষ্ট করে না, সিক্রেটটি অ্যাক্সেস করার চেষ্টা করে, তবে এটি একটি 'undefined' ভ্যালু পাবে:

    নোড.জেএস

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

    পাইথন

    @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.
    

Once your function is deployed, it will have access to the secret value. Only functions that specifically include a secret in their secrets option will have access to that secret as an environment variable. This helps you make sure that secret values are only available where they're needed, reducing the risk of accidentally leaking a secret.

গোপনীয়তা পরিচালনা করা

আপনার সিক্রেটগুলো পরিচালনা করতে Firebase CLI ব্যবহার করুন। এভাবে সিক্রেটগুলো পরিচালনা করার সময় মনে রাখবেন যে, CLI-এর কিছু পরিবর্তনের জন্য আপনাকে সংশ্লিষ্ট ফাংশনগুলো পরিবর্তন এবং/অথবা পুনরায় ডিপ্লয় করতে হতে পারে। বিশেষত:

  • যখনই আপনি কোনো সিক্রেটের জন্য একটি নতুন মান সেট করবেন, আপনাকে অবশ্যই সেই সিক্রেটটিকে রেফারেন্স করে এমন সমস্ত ফাংশন পুনরায় ডিপ্লয় করতে হবে, যাতে তারা সর্বশেষ মানটি গ্রহণ করতে পারে।
  • আপনি যদি কোনো সিক্রেট মুছে ফেলেন, তবে নিশ্চিত করুন যে আপনার ডেপ্লয় করা কোনো ফাংশন যেন সেই সিক্রেটটিকে রেফারেন্স না করে। যে ফাংশনগুলো মুছে ফেলা সিক্রেট ভ্যালু ব্যবহার করে, সেগুলো নীরবে ব্যর্থ হবে।

সিক্রেট ম্যানেজমেন্টের জন্য Firebase সিএলআই কমান্ডগুলোর একটি সারসংক্ষেপ নিচে দেওয়া হলো:

# 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 CLI প্রয়োজন অনুযায়ী অব্যবহৃত সিক্রেট ভার্সনগুলো স্বয়ংক্রিয়ভাবে মুছে ফেলার চেষ্টা করে, যেমন যখন আপনি সিক্রেটের একটি নতুন ভার্সন সহ ফাংশন ডেপ্লয় করেন। এছাড়াও, আপনি functions:secrets:destroy এবং functions:secrets:prune ব্যবহার করে সক্রিয়ভাবে অব্যবহৃত সিক্রেটগুলো পরিষ্কার করতে পারেন।

Secret Manager একটি সিক্রেটের উপর প্রতি মাসে ১০,০০০টি বিলবিহীন অ্যাক্সেস অপারেশনের অনুমতি দেয়। ফাংশন ইনস্ট্যান্সগুলো প্রতিবার কোল্ড স্টার্ট হওয়ার সময় শুধুমাত্র তাদের secrets অপশনে নির্দিষ্ট করা সিক্রেটগুলোই পড়ে। যদি আপনার অনেকগুলো ফাংশন ইনস্ট্যান্স প্রচুর সিক্রেট পড়ে, তাহলে আপনার প্রজেক্ট এই সীমা অতিক্রম করতে পারে, সেক্ষেত্রে আপনাকে প্রতি ১০,০০০ অ্যাক্সেস অপারেশনের জন্য $০.০৩ চার্জ করা হবে।

আরও তথ্যের জন্য, Secret Manager প্রাইসিং দেখুন।

এমুলেটর সমর্থন

ডটএনভ (dotenv) ব্যবহার করে পরিবেশ কনফিগারেশনটি একটি স্থানীয় Cloud Functions এমুলেটরের সাথে আন্তঃকার্যকরীভাবে কাজ করার জন্য ডিজাইন করা হয়েছে।

When using a local Cloud Functions emulator, you can override environment variables for your project by setting up a .env.local file. Contents of .env.local take precedence over .env and the project-specific .env file.

উদাহরণস্বরূপ, একটি প্রজেক্টে এই তিনটি ফাইল অন্তর্ভুক্ত থাকতে পারে, যেগুলিতে ডেভেলপমেন্ট এবং লোকাল টেস্টিং-এর জন্য মানগুলো সামান্য ভিন্ন:

.env .env.dev .env.local
গ্রহ=পৃথিবী

দর্শক = মানুষ

দর্শক = ডেভ মানুষ দর্শক = স্থানীয় মানুষ

স্থানীয় প্রেক্ষাপটে চালু করা হলে, এমুলেটরটি দেখানো অনুযায়ী এনভায়রনমেন্ট ভেরিয়েবলগুলো লোড করে:

  $ 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-এ মাইগ্রেট করুন। আপনার কনফিগারেশন মাইগ্রেট করার সবচেয়ে কার্যকর এবং নিরাপদ উপায় হিসেবে এটি জোরালোভাবে সুপারিশ করা হয়।

  1. Firebase CLI দিয়ে কনফিগারেশন এক্সপোর্ট করুন

    আপনার বিদ্যমান এনভায়রনমেন্ট কনফিগকে ক্লাউড সিক্রেট ম্যানেজারের একটি নতুন সিক্রেটে এক্সপোর্ট করতে 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```
    
  2. সিক্রেট বাইন্ড করতে ফাংশন কোড আপডেট করুন

    ক্লাউড সিক্রেট ম্যানেজারে নতুন সিক্রেটে সংরক্ষিত কনফিগারেশন ব্যবহার করতে, আপনার ফাংশন সোর্সে defineJsonSecret API ব্যবহার করুন। এছাড়াও, নিশ্চিত করুন যে প্রয়োজনীয় সমস্ত ফাংশনের সাথে সিক্রেটগুলো বাইন্ড করা আছে।

    আগে

    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;
        // ...
    });
    
  3. ফাংশন স্থাপন করুন

    পরিবর্তনগুলি প্রয়োগ করতে এবং গোপনীয় অনুমতিগুলি সংযুক্ত করতে আপনার আপডেট করা ফাংশনগুলি ডিপ্লয় করুন।

    firebase deploy --only functions:<your-function-name>
    

স্বয়ংক্রিয়ভাবে পূরণ করা পরিবেশ ভেরিয়েবল

কিছু এনভায়রনমেন্ট ভেরিয়েবল আছে যা ফাংশন রানটাইমে এবং স্থানীয়ভাবে অনুকরণ করা ফাংশনগুলিতে স্বয়ংক্রিয়ভাবে যুক্ত হয়ে যায়। এর মধ্যে রয়েছে Google Cloud দ্বারা যুক্ত হওয়া ভেরিয়েবলগুলো , এবং সেইসাথে ফায়ারবেস-এর জন্য নির্দিষ্ট একটি এনভায়রনমেন্ট ভেরিয়েবল:

process.env.FIREBASE_CONFIG : নিম্নলিখিত ফায়ারবেস প্রোজেক্ট কনফিগারেশন তথ্য প্রদান করে:

{
  databaseURL: 'https://DATABASE_NAME.firebaseio.com',
  storageBucket: 'PROJECT_ID.firebasestorage.app',
  projectId: 'PROJECT_ID'
}

মনে রাখবেন যে, আপনার প্রোজেক্টে বরাদ্দ করা রিসোর্সগুলোর ওপর নির্ভর করে আপনার প্রকৃত Firebase কনফিগারেশনের মানগুলো ভিন্ন হতে পারে।

আপনি যখন কোনো আর্গুমেন্ট ছাড়া Firebase Admin SDK ইনিশিয়ালাইজ করেন, তখন এই কনফিগারেশনটি স্বয়ংক্রিয়ভাবে প্রয়োগ হয়। আপনি যদি জাভাস্ক্রিপ্টে ফাংশন লিখে থাকেন, তাহলে এইভাবে ইনিশিয়ালাইজ করুন:

const admin = require('firebase-admin');
admin.initializeApp();

আপনি যদি টাইপস্ক্রিপ্টে ফাংশন লেখেন, তাহলে এইভাবে ইনিশিয়ালাইজ করুন:

import * as functions from 'firebase-functions/v1';
import * as admin from 'firebase-admin';
import 'firebase-functions/v1';
admin.initializeApp();

সার্ভিস অ্যাকাউন্টের ক্রেডেনশিয়াল ব্যবহার করে ডিফল্ট প্রজেক্ট কনফিগারেশন দিয়ে অ্যাডমিন SDK ইনিশিয়ালাইজ করার প্রয়োজন হলে, আপনি একটি ফাইল থেকে ক্রেডেনশিয়ালগুলো লোড করে FIREBASE_CONFIG এ এইভাবে যোগ করতে পারেন:

serviceAccount = require('./serviceAccount.json');

const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);