एसएसआर (सर्वर साइड रेंडरिंग) की मदद से, डाइनैमिक वेब ऐप्लिकेशन में Firebase का इस्तेमाल करना

अगर आपने Firebase JS SDK टूल या अन्य Firebase क्लाइंट SDK टूल का इस्तेमाल किया है, तो आपको FirebaseApp इंटरफ़ेस के बारे में पता होगा. साथ ही, आपको यह भी पता होगा कि इसका इस्तेमाल करके ऐप्लिकेशन इंस्टेंस को कैसे कॉन्फ़िगर किया जाता है. सर्वर साइड पर इसी तरह की कार्रवाइयां करने के लिए, Firebase FirebaseServerApp उपलब्ध कराता है.

FirebaseServerApp, FirebaseApp का एक वैरिएंट है. इसका इस्तेमाल सर्वर-साइड रेंडरिंग (एसएसआर) एनवायरमेंट में किया जाता है. इसमें ऐसे टूल शामिल हैं जो क्लाइंट साइड रेंडरिंग (सीएसआर) / सर्वर-साइड रेंडरिंग के बीच के अंतर को कम करके, Firebase सेशन को जारी रखते हैं. इन टूल और रणनीतियों की मदद से, Firebase की मदद से बनाए गए और Google के एनवायरमेंट, जैसे कि Firebase App Hosting में डिप्लॉय किए गए डाइनैमिक वेब ऐप्लिकेशन को बेहतर बनाया जा सकता है.

FirebaseServerApp का इस्तेमाल इन कामों के लिए किया जा सकता है:

  • उपयोगकर्ता के कॉन्टेक्स्ट में सर्वर-साइड कोड को एक्ज़ीक्यूट करता है. इसके उलट, Firebase Admin SDK के पास एडमिन के सभी अधिकार होते हैं.
  • एसएसआर एनवायरमेंट में App Check के इस्तेमाल की सुविधा चालू करें.
  • क्लाइंट में बनाए गए Firebase Auth सेशन को जारी रखता है.

FirebaseServerApp का लाइफ़साइकल

सर्वर-साइड रेंडरिंग (एसएसआर) फ़्रेमवर्क और ब्राउज़र के अलावा अन्य रनटाइम, जैसे कि क्लाउड वर्कर, कई बार एक्ज़ीक्यूट होने वाले रिसॉर्स का फिर से इस्तेमाल करके, इनिशियलाइज़ेशन के समय को ऑप्टिमाइज़ करते हैं. FirebaseServerApp को इन एनवायरमेंट के हिसाब से डिज़ाइन किया गया है. इसके लिए, रेफ़रंस काउंट मैकेनिज़्म का इस्तेमाल किया जाता है. अगर कोई ऐप्लिकेशन, पिछले initializeServerApp के जैसे ही पैरामीटर के साथ initializeServerApp को शुरू करता है, तो उसे वही FirebaseServerApp इंस्टेंस मिलता है जो पहले से शुरू किया गया था. इससे, बिना किसी वजह के इनिशियलाइज़ेशन ओवरहेड और मेमोरी के बंटवारे को कम किया जा सकता है. जब किसी FirebaseServerApp इंस्टेंस पर deleteApp को लागू किया जाता है, तो यह रेफ़रंस की गिनती को कम कर देता है. साथ ही, रेफ़रंस की गिनती शून्य होने के बाद इंस्टेंस को हटा दिया जाता है.

FirebaseServerApp इंस्टेंस मिटाना

FirebaseServerApp इंस्टेंस पर deleteApp को कब कॉल करना है, यह जानना मुश्किल हो सकता है. खास तौर पर, अगर कई एसिंक्रोनस कार्रवाइयां एक साथ चल रही हों. FirebaseServerAppSettings एट्रिब्यूट का releaseOnDeref फ़ील्ड, इस प्रोसेस को आसान बनाने में मदद करता है. अगर आपने releaseOnDeref को अनुरोध के स्कोप के लाइफ़स्पैन वाले ऑब्जेक्ट का रेफ़रंस असाइन किया है (उदाहरण के लिए, एसएसआर अनुरोध का हेडर ऑब्जेक्ट), तो फ़्रेमवर्क के हेडर ऑब्जेक्ट को वापस पाने पर, releaseOnDeref अपने रेफ़रंस की संख्या कम कर देगा.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);
  ...
}

क्लाइंट पर बनाए गए पुष्टि किए गए सेशन फिर से शुरू करें

जब FirebaseServerApp के किसी इंस्टेंस को Auth ID टोकन के साथ शुरू किया जाता है, तो यह क्लाइंट-साइड रेंडरिंग (सीएसआर) और सर्वर-साइड रेंडरिंग (एसएसआर) एनवायरमेंट के बीच, पुष्टि किए गए उपयोगकर्ता के सेशन को ब्रिज करने की सुविधा चालू करता है. FirebaseServerApp ऑब्जेक्ट के साथ शुरू किए गए Firebase Auth SDK के इंस्टेंस में, Auth ID टोकन होता है. यह इंस्टेंस, शुरू होने पर उपयोगकर्ता को अपने-आप साइन इन करने की कोशिश करेगा. इसके लिए, ऐप्लिकेशन को साइन-इन करने के किसी भी तरीके को लागू करने की ज़रूरत नहीं होगी.

Auth आईडी टोकन देने से, ऐप्लिकेशन को क्लाइंट पर Auth के किसी भी साइन-इन तरीके का इस्तेमाल करने की अनुमति मिलती है. इससे यह पक्का होता है कि सेशन सर्वर-साइड पर जारी रहे. ऐसा उन साइन-इन तरीकों के लिए भी होता है जिनके लिए उपयोगकर्ता के इंटरैक्शन की ज़रूरत होती है. इसके अलावा, यह सर्वर पर ज़्यादा लोड डालने वाले कामों को ऑफ़लोड करने की सुविधा देता है. जैसे, पुष्टि की गई Firestore क्वेरी. इससे आपके ऐप्लिकेशन की रेंडरिंग परफ़ॉर्मेंस बेहतर होती है.

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

एसएसआर एनवायरमेंट में App Check का इस्तेमाल करना

App Check लागू करने के लिए, App Check SDK टूल के उस इंस्टेंस का इस्तेमाल किया जाता है जिसे Firebase SDK टूल, getToken को इंटरनल तौर पर कॉल करने के लिए इस्तेमाल करते हैं. इसके बाद, जनरेट हुए टोकन को Firebase की सभी सेवाओं के अनुरोधों में शामिल किया जाता है. इससे बैकएंड को ऐप्लिकेशन की पुष्टि करने की अनुमति मिलती है.

हालांकि, App Check SDK को ऐप्लिकेशन की पुष्टि करने के लिए, कुछ खास अनुमानित तरीकों को ऐक्सेस करने के लिए ब्राउज़र की ज़रूरत होती है. इसलिए, इसे सर्वर एनवायरमेंट में शुरू नहीं किया जा सकता.

FirebaseServerApp एक विकल्प देता है. अगर FirebaseServerApp शुरू करने के दौरान, क्लाइंट से जनरेट किया गया App Check टोकन दिया जाता है, तो Firebase सेवाओं को शुरू करते समय, Firebase प्रॉडक्ट SDK टूल इसका इस्तेमाल करेंगे. इससे App Check 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.

क्लाइंट टोकन को सर्वर साइड रेंडरिंग फ़ेज़ में पास करना

क्लाइंट से सर्वर साइड रेंडरिंग (एसएसआर) फ़ेज़ में, पुष्टि किए गए Auth ID टोकन (और ऐप्लिकेशन की जांच करने वाले टोकन) ट्रांसमिट करने के लिए, सर्विस वर्कर का इस्तेमाल करें. इस तरीके में, फ़ेच के उन अनुरोधों को इंटरसेप्ट किया जाता है जो एसएसआर को ट्रिगर करते हैं. साथ ही, टोकन को अनुरोध के हेडर में जोड़ा जाता है.

Firebase Auth सेवा देने वाले वर्कर के रेफ़रंस के तौर पर लागू करने के लिए, सर्विस वर्कर की मदद से सेशन मैनेज करना लेख पढ़ें. FirebaseServerApp को शुरू करने के लिए, हेडर से इन टोकन को पार्स करने का तरीका बताने वाले कोड के लिए, सर्वर साइड में किए गए बदलाव भी देखें.

एसएसआर एनवायरमेंट में Firestore का इस्तेमाल करना

सर्वर साइड रेंडरिंग (एसएसआर) का इस्तेमाल करके वेब ऐप्लिकेशन बनाते समय, आपको अक्सर सर्वर और क्लाइंट के बीच डेटा शेयर करना पड़ता है. इससे परफ़ॉर्मेंस और उपयोगकर्ता अनुभव को ऑप्टिमाइज़ किया जा सकता है. Firestore SDK, सीरियलाइज़ेशन टूल उपलब्ध कराता है. इनकी मदद से, सर्वर पर स्नैपशॉट और खास तरह के डेटा कैप्चर किए जा सकते हैं. साथ ही, इन्हें सीधे तौर पर क्लाइंट-साइड कॉम्पोनेंट को पास किया जा सकता है. इस प्रोसेस से, बार-बार फ़ेच करने की ज़रूरत नहीं पड़ती. ऐसा इसलिए होता है, क्योंकि क्लाइंट को SSR फ़ेज़ के दौरान पहले से फ़ेच किए गए डेटा का इस्तेमाल करके, स्टेट को हाइड्रेट करने की सुविधा मिलती है. इसके अलावा, इन क्रम से की गई कार्रवाइयों को रीयल-टाइम लिसनर में बदला जा सकता है. इससे यह पक्का किया जा सकता है कि आपका ऐप्लिकेशन, डेटाबेस के साथ सिंक रहे.

इस सेक्शन में, क्लाइंट-साइड कॉम्पोनेंट में, सर्वर-साइड रेंडरिंग (एसएसआर) फ़ेज़ के दौरान वापस लाए गए डेटा को फिर से इस्तेमाल करने का तरीका बताया गया है.

डेटा टाइप को क्रम से लगाना

Firestore के कुछ डेटा टाइप, अपने डेटा को सीरियलाइज़ किए जा सकने वाले फ़ॉर्मैट में बदलने के लिए 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();

डेटा टाइप को डीसीरियलाइज़ करना

Firestore के डेटा टाइप में, स्टैटिक तरीके से काम करने वाला fromJSON शामिल होता है. इसका इस्तेमाल, क्रम से लगाए गए डेटा को Firestore के इस्तेमाल किए जा सकने वाले डेटा टाइप में बदलने के लिए किया जाता है.

उदाहरण के लिए, यहां दिए गए कोड में Bytes डेटा टाइप को डिसिरियलाइज़ किया गया है:

import {
  Bytes
} from 'firebase/firestore';

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

Firestore स्नैपशॉट को क्रम से लगाना और क्रम से हटाना

Firestore के डेटा टाइप की तरह ही, 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);

सीरियल वाले स्नैपशॉट सुनने वाले लोग

एसएसआर फ़ेज़ के दौरान क्वेरी किया गया डेटा, शुरुआती सीएसआर रेंडर के लिए अहम होता है. हालांकि, आपको उस जानकारी के रीयल-टाइम अपडेट के लिए, Firestore सेवा की निगरानी करनी पड़ सकती है.

अगर आपके ऐप्लिकेशन को रीयल-टाइम में अपडेट की ज़रूरत है, तो onSnapshotResume फ़ंक्शन का इस्तेमाल करके, Firestore SnapshotListener को क्रम से लगाए गए Snapshot डेटा के साथ शुरू किया जा सकता है. उदाहरण के लिए:

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