ক্লাউড ফাংশন সহ রিয়েলটাইম ডাটাবেস প্রসারিত করুন


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

একটি সাধারণ জীবনচক্রে, একটি Firebase Realtime Database ফাংশন নিম্নলিখিতগুলি করে:

  1. একটি নির্দিষ্ট Realtime Database পাথ পরিবর্তনের জন্য অপেক্ষা করে।
  2. একটি ঘটনা ঘটলে ট্রিগার করে এবং তার কার্য সম্পাদন করে।
  3. সেই পাথে সংরক্ষিত ডেটার একটি স্ন্যাপশট ধারণ করে এমন একটি ডেটা অবজেক্ট গ্রহণ করে।

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

ফাংশন অবস্থান সেট করা হচ্ছে

একটি Realtime Database উদাহরণের অবস্থান এবং ফাংশনের অবস্থানের মধ্যে দূরত্ব উল্লেখযোগ্য নেটওয়ার্ক লেটেন্সি তৈরি করতে পারে। এছাড়াও, অঞ্চলগুলির মধ্যে একটি অমিলের ফলে স্থাপনা ব্যর্থ হতে পারে। এই পরিস্থিতিগুলি এড়াতে, ফাংশন অবস্থান নির্দিষ্ট করুন যাতে এটি ডাটাবেস ইনস্ট্যান্স অবস্থানের সাথে মেলে।

Realtime Database ইভেন্টগুলি পরিচালনা করা

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

Realtime Database ইভেন্টগুলিতে প্রতিক্রিয়া জানাতে এই হ্যান্ডলারগুলি উপলব্ধ:

Node.js পাইথন
  • onValueWritten() যখন Realtime Database ডেটা তৈরি, আপডেট করা বা মুছে ফেলা হয় তখন ট্রিগার হয়।
  • onValueCreated() শুধুমাত্র তখনই ট্রিগার হয় যখন Realtime Database ডেটা তৈরি করা হয়।
  • onValueUpdated() শুধুমাত্র তখনই ট্রিগার হয় যখন Realtime Database ডেটা আপডেট করা হয়।
  • onValueDeleted() শুধুমাত্র তখনই ট্রিগার হয় যখন Realtime Database ডেটা মুছে ফেলা হয়।
  • on_value_written() যখন Realtime Database ডেটা তৈরি, আপডেট করা বা মুছে ফেলা হয় তখন ট্রিগার হয়।
  • on_value_created() শুধুমাত্র তখনই ট্রিগার হয় যখন Realtime Database ডেটা তৈরি হয়।
  • on_value_updated() শুধুমাত্র তখনই ট্রিগার হয় যখন Realtime Database ডেটা আপডেট করা হয়।
  • on_value_deleted() শুধুমাত্র তখনই ট্রিগার হয় যখন Realtime Database ডেটা মুছে ফেলা হয়।

প্রয়োজনীয় মডিউল আমদানি করুন

আপনার ফাংশন উত্সে, আপনাকে অবশ্যই SDK মডিউলগুলি আমদানি করতে হবে যা আপনি ব্যবহার করতে চান৷ এই নমুনার জন্য, Realtime Database লেখার জন্য Firebase Admin SDK মডিউল সহ HTTP এবং Realtime Database মডিউলগুলি আমদানি করা প্রয়োজন৷

Node.js পাইথন
// The Cloud Functions for Firebase SDK to setup triggers and logging.
const {onRequest} = require("firebase-functions/v2/https");
const {onValueCreated} = require("firebase-functions/v2/database");
const {logger} = require("firebase-functions");

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require("firebase-admin");
admin.initializeApp();
# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import db_fn, https_fn

# The Firebase Admin SDK to access the Firebase Realtime Database.
from firebase_admin import initialize_app, db

app = initialize_app()

উদাহরণ এবং পথ নির্দিষ্ট করুন

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

যেমন:

Node.js পাইথন
// All Realtime Database instances in default function region us-central1 at path "/user/{uid}"
// There must be at least one Realtime Database present in us-central1.
const onWrittenFunctionDefault = onValueWritten("/user/{uid}", (event) => {
  // …
});

// Instance named "my-app-db-2", at path "/user/{uid}".
// The "my-app-db-2" instance must exist in this region.
const OnWrittenFunctionInstance = onValueWritten(
  {
    ref: "/user/{uid}",
    instance: "my-app-db-2"
    // This example assumes us-central1, but to set location:
    // region: "europe-west1"
  },
  (event) => {
    // …
  }
);

// Instance with "my-app-db-" prefix, at path "/user/{uid}", where uid ends with @gmail.com.
// There must be at least one Realtime Database with "my-app-db-*" prefix in this region.
const onWrittenFunctionInstance = onValueWritten(
  {
    ref: "/user/{uid=*@gmail.com}",
    instance: "my-app-db-*"
    // This example assumes us-central1, but to set location:
    // region: "europe-west1"
  },
  (event) => {
    // …
  }
);
# All Realtime Database instances in default function region us-central1 at path "/user/{uid}"
# There must be at least one Realtime Database present in us-central1.
@db_fn.on_value_written(r"/user/{uid}")
def onwrittenfunctiondefault(event: db_fn.Event[db_fn.Change]):
    # ...
    pass

# Instance named "my-app-db-2", at path "/user/{uid}".
# The "my-app-db-2" instance must exist in this region.
@db_fn.on_value_written(
    reference=r"/user/{uid}",
    instance="my-app-db-2",
    # This example assumes us-central1, but to set location:
    # region="europe-west1",
)
def on_written_function_instance(event: db_fn.Event[db_fn.Change]):
    # ...
    pass

# Instance with "my-app-db-" prefix, at path "/user/{uid}", where uid ends with @gmail.com.
# There must be at least one Realtime Database with "my-app-db-*" prefix in this region.
@db_fn.on_value_written(
    reference=r"/user/{uid=*@gmail.com}",
    instance="my-app-db-*",
    # This example assumes us-central1, but to set location:
    # region="europe-west1",
)
def on_written_function_instance(event: db_fn.Event[db_fn.Change]):
    # ...
    pass

এই পরামিতিগুলি আপনার ফাংশনকে Realtime Database উদাহরণের মধ্যে একটি নির্দিষ্ট পথে লেখাগুলি পরিচালনা করতে নির্দেশ করে।

পাথ স্পেসিফিকেশন সব লেখার সাথে মেলে যা একটি পাথকে স্পর্শ করে, এর নিচে যেকোনও লেখা সহ। আপনি যদি /foo/bar হিসাবে আপনার ফাংশনের জন্য পাথ সেট করেন তবে এটি এই উভয় অবস্থানের ইভেন্টের সাথে মিলে যায়:

 /foo/bar
 /foo/bar/baz/really/deep/path

উভয় ক্ষেত্রেই, Firebase ব্যাখ্যা করে যে ইভেন্টটি /foo/bar এ ঘটে এবং ইভেন্ট ডেটা /foo/bar এ পুরানো এবং নতুন ডেটা অন্তর্ভুক্ত করে। ইভেন্ট ডেটা বড় হলে, আপনার ডাটাবেসের রুটের কাছে একটি একক ফাংশনের পরিবর্তে গভীর পাথে একাধিক ফাংশন ব্যবহার করার কথা বিবেচনা করুন। সেরা পারফরম্যান্সের জন্য, শুধুমাত্র সম্ভাব্য গভীরতম স্তরে ডেটার অনুরোধ করুন৷

ওয়াইল্ডকার্ডিং এবং ক্যাপচারিং

ক্যাপচার করার জন্য আপনি {key} , {key=*} , {key=prefix*} , {key=*suffix} ব্যবহার করতে পারেন। * , prefix* , *suffix । দ্রষ্টব্য: ** মাল্টি-সেগমেন্ট ওয়াইল্ডকার্ডিং প্রতিনিধিত্ব করে, যা Realtime Database সমর্থন করে না। পাথ প্যাটার্ন বুঝতে দেখুন.

পথ ওয়াইল্ডকার্ডিং। আপনি একটি ওয়াইল্ডকার্ড হিসাবে একটি পথ উপাদান নির্দিষ্ট করতে পারেন:

  • তারকাচিহ্ন ব্যবহার করে, * । উদাহরণস্বরূপ, foo/* যেকোনো শিশুর সাথে foo/ নিচের নোড অনুক্রমের এক স্তরের সাথে মেলে।
  • ঠিক তারকাচিহ্ন সম্বলিত একটি সেগমেন্ট ব্যবহার করে, * । উদাহরণস্বরূপ, foo/app*-us app উপসর্গ এবং -us প্রত্যয় সহ foo/ নিচের যেকোনো চাইল্ড সেগমেন্টের সাথে মেলে।

ওয়াইল্ডকার্ড সহ পাথগুলি একাধিক ইভেন্টের সাথে মেলে, উদাহরণস্বরূপ, একটি একক লেখা। একটি সন্নিবেশ

{
  "foo": {
    "hello": "world",
    "firebase": "functions"
  }
}

"/foo/*" পাথের সাথে দুবার মেলে: একবার "hello": "world" এবং আবার "firebase": "functions" এর সাথে।

পাথ ক্যাপচারিং। আপনি আপনার ফাংশন কোডে (যেমন /user/{uid} , /user/{uid=*-us} ) ব্যবহার করার জন্য নামযুক্ত ভেরিয়েবলের মধ্যে পাথ ম্যাচগুলি ক্যাপচার করতে পারেন।

ক্যাপচার ভেরিয়েবলের মান আপনার ফাংশনের database.DatabaseEvent.params অবজেক্টের মধ্যে উপলব্ধ।

উদাহরণ ওয়াইল্ডকার্ডিং। আপনি ওয়াইল্ডকার্ডিং ব্যবহার করে একটি উদাহরণ উপাদান নির্দিষ্ট করতে পারেন। একটি উদাহরণ ওয়াইল্ডকার্ডে উপসর্গ, প্রত্যয় বা উভয়ই থাকতে পারে (যেমন my-app-*-prod )।

ওয়াইল্ডকার্ড এবং ক্যাপচার রেফারেন্স

Cloud Functions (২য় জেন) এবং Realtime Database সাথে, ref এবং instance নির্দিষ্ট করার সময় একটি প্যাটার্ন ব্যবহার করা যেতে পারে। প্রতিটি ট্রিগার ইন্টারফেসে একটি ফাংশন স্কোপ করার জন্য নিম্নলিখিত বিকল্প থাকবে:

উল্লেখ ref instance নির্দিষ্ট করা আচরণ
একক ( /foo/bar ) উল্লেখ করছি না ফাংশন অঞ্চলের সমস্ত দৃষ্টান্তে স্কোপ হ্যান্ডলার।
একক ( /foo/bar ) একক ( 'my-new-db' ) ফাংশন অঞ্চলে নির্দিষ্ট উদাহরণে স্কোপ হ্যান্ডলার।
একক ( /foo/bar ) প্যাটার্ন ( 'inst-prefix*' ) ফাংশন অঞ্চলের প্যাটার্নের সাথে মেলে এমন সমস্ত উদাহরণে স্কোপ হ্যান্ডলার।
প্যাটার্ন ( /foo/{bar} ) উল্লেখ করছি না ফাংশন অঞ্চলের সমস্ত দৃষ্টান্তে স্কোপ হ্যান্ডলার।
প্যাটার্ন ( /foo/{bar} ) একক ( 'my-new-db' ) ফাংশন অঞ্চলে নির্দিষ্ট উদাহরণে স্কোপ হ্যান্ডলার।
প্যাটার্ন ( /foo/{bar} ) প্যাটার্ন ( 'inst-prefix*' ) ফাংশন অঞ্চলের প্যাটার্নের সাথে মেলে এমন সমস্ত উদাহরণে স্কোপ হ্যান্ডলার।

ইভেন্ট ডেটা পরিচালনা করুন

যখন একটি Realtime Database ইভেন্ট ট্রিগার হয়, এটি আপনার হ্যান্ডলার ফাংশনে একটি Event অবজেক্ট পাস করে। এই বস্তুটির একটি data বৈশিষ্ট্য রয়েছে, যা তৈরি এবং মুছে ফেলার ইভেন্টগুলির জন্য তৈরি বা মুছে ফেলা ডেটার একটি স্ন্যাপশট রয়েছে৷

এই উদাহরণে, ফাংশনটি রেফারেন্সড পাথের জন্য ডেটা পুনরুদ্ধার করে, সেই অবস্থানের স্ট্রিংটিকে বড় হাতের অক্ষরে রূপান্তর করে এবং সেই পরিবর্তিত স্ট্রিংটিকে ডাটাবেসে লেখে:

Node.js পাইথন
// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
// for all databases in 'us-central1'
exports.makeuppercase = onValueCreated(
    "/messages/{pushId}/original",
    (event) => {
    // Grab the current value of what was written to the Realtime Database.
      const original = event.data.val();
      logger.log("Uppercasing", event.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing
      // asynchronous tasks inside a function, such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the
      // Realtime Database returns a Promise.
      return event.data.ref.parent.child("uppercase").set(uppercase);
    },
);
@db_fn.on_value_created(reference="/messages/{pushId}/original")
def makeuppercase(event: db_fn.Event[Any]) -> None:
    """Listens for new messages added to /messages/{pushId}/original and
    creates an uppercase version of the message to /messages/{pushId}/uppercase
    """

    # Grab the value that was written to the Realtime Database.
    original = event.data
    if not isinstance(original, str):
        print(f"Not a string: {event.reference}")
        return

    # Use the Admin SDK to set an "uppercase" sibling.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    parent = db.reference(event.reference).parent
    if parent is None:
        print("Message can't be root node.")
        return
    parent.child("uppercase").set(upper)

আগের মান পড়া

ইভেন্টগুলি write বা update জন্য, data প্রপার্টি হল একটি Change অবজেক্ট যাতে দুটি স্ন্যাপশট থাকে যা ট্রিগারিং ইভেন্টের আগে এবং পরে ডেটার অবস্থাকে উপস্থাপন করে। Change অবজেক্টের একটি before প্রোপার্টি রয়েছে যা আপনাকে ইভেন্টের আগে Realtime Database কী সংরক্ষিত হয়েছিল তা পরিদর্শন করতে দেয় এবং একটি after প্রোপার্টি যা ইভেন্ট হওয়ার পরে ডেটার অবস্থা উপস্থাপন করে।

উদাহরণস্বরূপ, before সম্পত্তিটি নিশ্চিত করতে ব্যবহার করা যেতে পারে যে ফাংশনটি প্রথমবার তৈরি করার সময় কেবলমাত্র টেক্সট বড় হাতের হয়:

Node.js পাইথন
  exports makeUppercase = onValueWritten("/messages/{pushId}/original", (event) => {
        // Only edit data when it is first created.
        if (event.data.before.exists()) {
          return null;
        }
        // Exit when the data is deleted.
        if (!event.data.after.exists()) {
          return null;
        }
        // Grab the current value of what was written to the Realtime Database.
        const original = event.data.after.val();
        console.log('Uppercasing', event.params.pushId, original);
        const uppercase = original.toUpperCase();
        // You must return a Promise when performing asynchronous tasks inside a Functions such as
        // writing to the Firebase Realtime Database.
        // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
        return event.data.after.ref.parent.child('uppercase').set(uppercase);
      });
@db_fn.on_value_written(reference="/messages/{pushId}/original")
def makeuppercase2(event: db_fn.Event[db_fn.Change]) -> None:
    """Listens for new messages added to /messages/{pushId}/original and
    creates an uppercase version of the message to /messages/{pushId}/uppercase
    """

    # Only edit data when it is first created.
    if event.data.before is not None:
        return

    # Exit when the data is deleted.
    if event.data.after is None:
        return

    # Grab the value that was written to the Realtime Database.
    original = event.data.after
    if not hasattr(original, "upper"):
        print(f"Not a string: {event.reference}")
        return

    # Use the Admin SDK to set an "uppercase" sibling.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    parent = db.reference(event.reference).parent
    if parent is None:
        print("Message can't be root node.")
        return
    parent.child("uppercase").set(upper)