SSR (সার্ভার-সাইড রেন্ডারিং) সহ গতিশীল ওয়েব অ্যাপ্লিকেশনগুলিতে Firebase ব্যবহার করুন, SSR (সার্ভার-সাইড রেন্ডারিং) সহ গতিশীল ওয়েব অ্যাপ্লিকেশনগুলিতে Firebase ব্যবহার করুন, SSR (সার্ভার-সাইড রেন্ডারিং) সহ গতিশীল ওয়েব অ্যাপ্লিকেশনগুলিতে Firebase ব্যবহার করুন

আপনি যদি Firebase JS SDK বা অন্যান্য Firebase ক্লায়েন্ট SDK নিয়ে কাজ করে থাকেন, তাহলে সম্ভবত আপনি FirebaseApp ইন্টারফেস এবং অ্যাপ ইনস্ট্যান্স কনফিগার করার পদ্ধতি সম্পর্কে পরিচিত। সার্ভার সাইডে অনুরূপ কার্যক্রম সহজ করার জন্য, Firebase, FirebaseServerApp প্রদান করে।

FirebaseServerApp হলো FirebaseApp এর একটি সংস্করণ, যা সার্ভার-সাইড রেন্ডারিং (SSR) পরিবেশে ব্যবহারের জন্য তৈরি। এতে এমন সব টুল রয়েছে যা ক্লায়েন্ট-সাইড রেন্ডারিং (CSR) এবং সার্ভার-সাইড রেন্ডারিং-এর মধ্যবর্তী পর্যায় অতিক্রম করে Firebase সেশন চালু রাখতে সাহায্য করে। এই টুল ও কৌশলগুলো Firebase দিয়ে তৈরি এবং Google-এর Firebase App Hosting মতো পরিবেশে ডেপ্লয় করা ডাইনামিক ওয়েব অ্যাপগুলোর মান উন্নত করতে সহায়তা করতে পারে।

FirebaseServerApp ব্যবহার করুন:

  • সম্পূর্ণ প্রশাসনিক অধিকার সম্পন্ন Firebase Admin SDK-এর বিপরীতে, এটি ব্যবহারকারীর প্রেক্ষাপটে সার্ভার-সাইড কোড কার্যকর করে।
  • SSR পরিবেশে অ্যাপ চেক-এর ব্যবহার সক্ষম করুন।
  • ক্লায়েন্টে তৈরি করা একটি ফায়ারবেস অথেন্টিকেশন সেশন চালিয়ে যান।

FirebaseServerApp জীবনচক্র

সার্ভার-সাইড রেন্ডারিং (SSR) ফ্রেমওয়ার্ক এবং ক্লাউড ওয়ার্কারের মতো অন্যান্য নন-ব্রাউজার রানটাইমগুলো একাধিক এক্সিকিউশনের মধ্যে রিসোর্স পুনঃব্যবহার করে ইনিশিয়ালাইজেশন সময় অপ্টিমাইজ করে। FirebaseServerApp একটি রেফারেন্স কাউন্ট মেকানিজম ব্যবহার করে এই পরিবেশগুলোর সাথে মানিয়ে চলার জন্য ডিজাইন করা হয়েছে। যদি কোনো অ্যাপ পূর্ববর্তী initializeServerApp এর মতো একই প্যারামিটার দিয়ে initializeServerApp কল করে, তবে এটি সেই একই FirebaseServerApp ইনস্ট্যান্সটি পায় যা ইতিমধ্যেই ইনিশিয়ালাইজ করা হয়েছিল। এটি অপ্রয়োজনীয় ইনিশিয়ালাইজেশন ওভারহেড এবং মেমরি অ্যালোকেশন কমিয়ে দেয়। যখন একটি FirebaseServerApp ইনস্ট্যান্সে deleteApp কল করা হয়, তখন এটি রেফারেন্স কাউন্ট কমিয়ে দেয় এবং রেফারেন্স কাউন্ট শূন্যে পৌঁছানোর পর ইনস্ট্যান্সটি মুক্ত হয়ে যায়।

FirebaseServerApp ইনস্ট্যান্সগুলি পরিষ্কার করা হচ্ছে

একটি FirebaseServerApp ইনস্ট্যান্সে কখন deleteApp কল করতে হবে তা জানা বেশ কঠিন হতে পারে, বিশেষ করে যদি আপনি সমান্তরালভাবে অনেকগুলো অ্যাসিঙ্ক্রোনাস অপারেশন চালান। FirebaseServerAppSettings এর releaseOnDeref ফিল্ডটি এই কাজটি সহজ করে দেয়। যদি আপনি releaseOnDeref রিকোয়েস্টের স্কোপের সমান জীবনকালের কোনো অবজেক্টের রেফারেন্স অ্যাসাইন করেন (উদাহরণস্বরূপ, SSR রিকোয়েস্টের হেডারস অবজেক্ট), তাহলে ফ্রেমওয়ার্ক যখন হেডার অবজেক্টটি রিক্লেইম করবে, তখন FirebaseServerApp তার রেফারেন্স কাউন্ট কমিয়ে দেবে। এর ফলে আপনার FirebaseServerApp ইনস্ট্যান্সটি স্বয়ংক্রিয়ভাবে পরিষ্কার হয়ে যায়।

releaseOnDeref এর একটি ব্যবহারের উদাহরণ নিচে দেওয়া হলো:

/// Next.js
import { headers } from 'next/headers'
import { FirebaseServerAppSettings, initializeServerApp} from "firebase/app";

export default async function Page() {
  const headersObj = await headers();
  let appSettings: FirebaseServerAppSettings = {};
  appSettings.releaseOnDeref = headersObj;
  const serverApp = initializeServerApp(firebaseConfig, appSettings);
  ...
}

ক্লায়েন্টে তৈরি প্রমাণীকৃত সেশনগুলি পুনরায় শুরু করুন।

যখন একটি Auth ID টোকেন দিয়ে FirebaseServerApp এর কোনো ইনস্ট্যান্স ইনিশিয়ালাইজ করা হয়, তখন এটি ক্লায়েন্ট-সাইড রেন্ডারিং (CSR) এবং সার্ভার-সাইড রেন্ডারিং (SSR) এনভায়রনমেন্টের মধ্যে অথেনটিকেটেড ইউজার সেশনগুলোর ব্রিজিং সক্ষম করে। Auth ID টোকেন ধারণকারী একটি FirebaseServerApp অবজেক্ট দিয়ে ইনিশিয়ালাইজ করা Firebase Auth SDK-এর ইনস্ট্যান্সগুলো, অ্যাপ্লিকেশনটির কোনো সাইন-ইন মেথড কল করার প্রয়োজন ছাড়াই, ইনিশিয়ালাইজেশনের সময়ই ইউজারকে সাইন ইন করার চেষ্টা করবে।

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

/// Next.js
import { initializeServerApp } from "firebase/app";
import { getAuth } from "firebase/auth";

// Replace the following with your app's
// Firebase project configuration
const firebaseConfig = {
  // ...
};

const firebaseServerAppSettings = {
  authIdToken: token  // See "Pass client tokens to the server side
                      // rendering phase" for an example on how transmit
                      // the token from the client and the server.
}

const serverApp =
  initializeServerApp(firebaseConfig,
                      firebaseServerAppSettings);
const serverAuth = getAuth(serverApp);

// FirebaseServerApp and Auth will now attempt
// to sign in the current user based on provided
// authIdToken.

SSR পরিবেশে অ্যাপ চেক ব্যবহার করুন

অ্যাপ চেক এনফোর্সমেন্ট একটি অ্যাপ চেক SDK ইনস্ট্যান্সের উপর নির্ভর করে, যা Firebase SDK-গুলো অভ্যন্তরীণভাবে getToken কল করার জন্য ব্যবহার করে। এর ফলে প্রাপ্ত টোকেনটি সমস্ত Firebase সার্ভিসে পাঠানো রিকোয়েস্টের সাথে অন্তর্ভুক্ত করা হয়, যা ব্যাকএন্ডকে অ্যাপটি ভ্যালিডেট করার সুযোগ দেয়।

তবে, যেহেতু অ্যাপ ভ্যালিডেশনের জন্য নির্দিষ্ট হিউরিস্টিকস অ্যাক্সেস করতে অ্যাপ চেক এসডিকে-র একটি ব্রাউজার প্রয়োজন হয়, তাই এটি সার্ভার পরিবেশে ইনিশিয়ালাইজ করা যায় না।

FirebaseServerApp একটি বিকল্প প্রদান করে। FirebaseServerApp চালু করার সময় যদি ক্লায়েন্ট-তৈরি একটি অ্যাপ চেক টোকেন প্রদান করা হয়, তবে Firebase পরিষেবাগুলি আহ্বান করার সময় Firebase প্রোডাক্ট SDK-গুলি সেটি ব্যবহার করবে, যার ফলে একটি অ্যাপ চেক SDK ইনস্ট্যান্সের প্রয়োজনীয়তা দূর হয়।

/// Next.js
import { initializeServerApp } from "firebase/app";

// Replace the following with your app's
// Firebase project configuration
const firebaseConfig = {
  // ...
};

const firebaseServerAppSettings = {
  appCheckToken: token // See "Pass client tokens to the server side
                       // rendering phase" for an example on how transmit
                       // the token from the client and the server.
}

const serverApp =
  initializeServerApp(firebaseConfig,
                      firebaseServerAppSettings);

// The App Check token will now be appended to all Firebase service requests.

ক্লায়েন্ট টোকেনগুলি সার্ভার-সাইড রেন্ডারিং পর্যায়ে প্রেরণ করুন

ক্লায়েন্ট থেকে সার্ভার-সাইড রেন্ডারিং (SSR) পর্যায়ে প্রমাণীকৃত Auth ID টোকেন (এবং App Check টোকেন) প্রেরণ করতে একটি সার্ভিস ওয়ার্কার ব্যবহার করুন। এই পদ্ধতিতে, SSR ট্রিগার করে এমন ফেচ রিকোয়েস্টগুলোকে ইন্টারসেপ্ট করা হয় এবং রিকোয়েস্ট হেডারে টোকেনগুলো যুক্ত করা হয়।

Firebase Auth সার্ভিস ওয়ার্কারের একটি রেফারেন্স ইমপ্লিমেন্টেশনের জন্য "সার্ভিস ওয়ার্কারদের সাথে সেশন ম্যানেজমেন্ট" দেখুন। এছাড়াও, FirebaseServerApp ইনিশিয়ালাইজেশনে ব্যবহারের জন্য হেডার থেকে এই টোকেনগুলি কীভাবে পার্স করতে হয়, তা প্রদর্শনকারী কোডের জন্য "সার্ভার সাইড পরিবর্তন" দেখুন।

SSR পরিবেশে ফায়ারস্টোর ব্যবহার করুন

সার্ভার-সাইড রেন্ডারিং (SSR) ব্যবহার করে ওয়েব অ্যাপ্লিকেশন তৈরি করার সময়, পারফরম্যান্স এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করার জন্য প্রায়শই সার্ভার এবং ক্লায়েন্টের মধ্যে ডেটা আদান-প্রদান করার প্রয়োজন হয়। ফায়ারস্টোর এসডিকে (Firestore SDK) এমন সিরিয়ালাইজেশন টুল সরবরাহ করে, যা আপনাকে সার্ভারে স্ন্যাপশট এবং নির্দিষ্ট ডেটা টাইপ ক্যাপচার করতে এবং সেগুলোকে সরাসরি আপনার ক্লায়েন্ট-সাইড কম্পোনেন্টগুলোতে পাঠাতে সাহায্য করে। এই প্রক্রিয়াটি অপ্রয়োজনীয় ফেচ (fetch) দূর করে, কারণ এটি ক্লায়েন্টকে SSR পর্যায়ে আগে থেকে ফেচ করা ডেটা ব্যবহার করে স্টেট হাইড্রেট (hydrate state) করতে সক্ষম করে। এছাড়াও, আপনি এই সিরিয়ালাইজড স্টেটগুলো থেকে রিয়েল-টাইম লিসেনারে (real-time listeners) যেতে পারেন, যা আপনার অ্যাপ্লিকেশনকে ডেটাবেসের সাথে সিঙ্ক্রোনাইজড (synchronized) রাখতে সাহায্য করে।

এই অংশে বর্ণনা করা হয়েছে কিভাবে সার্ভার-সাইড রেন্ডারিং (SSR) পর্যায়ে প্রাপ্ত ডেটা ক্লায়েন্ট-সাইড কম্পোনেন্টগুলোর মধ্যে পুনরায় ব্যবহার করা যায়।

সিরিয়ালাইজ ডেটা টাইপ

ফায়ারস্টোরের কিছু ডেটা টাইপ তাদের ডেটাকে সিরিয়ালাইজেবল ফরম্যাটে রূপান্তর করার জন্য একটি toJSON মেথড প্রদান করে। এর মধ্যে Bytes , GeoPoint , Timestamp এবং VectorValue এর মতো অবজেক্টের ইনস্ট্যান্সগুলো অন্তর্ভুক্ত।

একবার আপনার কাছে JSON ফরম্যাটে ডেটা চলে এলে, আপনি তা স্ট্যান্ডার্ড ফ্রেমওয়ার্ক পদ্ধতির মাধ্যমে সার্ভার থেকে ক্লায়েন্টে পাঠাতে পারেন, অথবা এমন কম্পোনেন্টগুলোর প্যারামিটার হিসেবে ব্যবহার করতে পারেন যা এই দুইয়ের মধ্যে সংযোগ স্থাপন করে। উদাহরণস্বরূপ:

import {
  Bytes
} from 'firebase/firestore';

const BYTES_DATA = new Uint8Array([0, 1, 2, 3, 4, 5]);
const bytes = Bytes.fromUint8Array(BYTES_DATA);
const bytesJSON = bytes.toJSON();

ডেটা টাইপ ডিসিরিয়ালাইজ করুন

ফায়ারস্টোর ডেটা টাইপগুলোতে fromJSON একটি স্ট্যাটিক মেথড রয়েছে, যা সিরিয়ালাইজড ডেটাকে একটি কার্যকর ফায়ারস্টোর ডেটা টাইপে রূপান্তর করে।

উদাহরণস্বরূপ, নিম্নলিখিতটি একটি Bytes ডেটা টাইপকে ডিসিরিয়ালাইজ করে:

import {
  Bytes
} from 'firebase/firestore';

// Assuming the same `bytesJSON` variable from the previous example.
const deserializedBytes = Bytes.fromJSON(bytesJSON);

ফায়ারস্টোর স্ন্যাপশট সিরিয়ালাইজ এবং ডিসিরিয়ালাইজ করুন

ফায়ারস্টোর ডেটা টাইপের মতোই, আপনি toJSON ব্যবহার করে DocumentSnapshot এবং QuerySnapshot এর ইনস্ট্যান্সগুলোকে সিরিয়ালাইজ করতে পারেন। তবে, সেগুলোকে ডিসিরিয়ালাইজ করার জন্য, একটি স্ট্যাটিক fromJSON মেথডের পরিবর্তে আপনাকে অবশ্যই documentSnapshotFromJSON এবং querySnapshotFromJSON নামক স্বতন্ত্র ফাংশনগুলো ব্যবহার করতে হবে।

উদাহরণস্বরূপ, একটি query অপারেশনের querySnapshot ফলাফল toJSON পদ্ধতি ব্যবহার করে সিরিয়ালাইজ করা যেতে পারে:

import {
  collection,
  getDocs,
  query,
  querySnapshotFromJSON
} from 'firebase/firestore';
// Assuming a configured instance of Firestore in the variable `firestore`.
const queryRef = query(collection(firestore, QUERY_PATH));
const querySnapshot = await getDocs(queryRef);
const querySnapshotJson = querySnapshot.toJSON();

তারপর, এই ডেটা ডিসিরিয়ালাইজ করা যেতে পারে:

import {
  querySnapshotFromJSON
} from 'firebase/firestore';

// deserializedSnapshot is an object of type QuerySnapshot:

const deserializedSnapshot =
  querySnapshotFromJSON(firestore, querySnapshotJson);

ধারাবাহিক স্ন্যাপশট সহ শ্রোতারা

যদিও এসএসআর পর্যায়ে কোয়েরি করা ডেটা আপনার প্রাথমিক সিএসআর রেন্ডারের জন্য মূল্যবান, তবুও সেই তথ্যের রিয়েল-টাইম আপডেটের জন্য আপনাকে ফায়ারস্টোর পরিষেবাটি নিরীক্ষণ করতে হতে পারে।

আপনার অ্যাপের যদি এই রিয়েল-টাইম আপডেটের প্রয়োজন হয়, তাহলে আপনি সিরিয়ালাইজড Snapshot ডেটা দিয়ে ফায়ারস্টোর SnapshotListener গুলিকে ইনিশিয়ালাইজ করতে onSnapshotResume ফাংশনটি ব্যবহার করতে পারেন। উদাহরণস্বরূপ:

const observer = {
  next: (qs) => {
    console.log("onSnapshot invoked: ", qs.data());
  },
  error: (e) => {
    console.log("error callback invoked: ", e.toString());
  }
};
const unsubscribe = onSnapshotResume(firestore, querySnapshotJson, observer);