استفاده از Firebase در برنامه‌های وب پویا با SSR (پردازش سمت سرور)

اگر با کیت توسعه نرم‌افزار Firebase JS یا دیگر کیت‌های توسعه نرم‌افزار کارخواه Firebase کار کرده باشید، احتمالاً با میانای FirebaseApp و نحوه استفاده از آن برای پیکربندی نمونه‌های برنامه آشنا هستید. برای تسهیل عملیات مشابه در سمت سرور، Firebase FirebaseServerApp را ارائه می‌دهد.

‫FirebaseServerApp گونه‌ای از FirebaseApp برای استفاده در محیط‌های پرداخت سمت سرور (SSR) است. این چارچوب شامل ابزارهایی برای ادامه دادن جلسه‌های Firebase است که تقسیم‌بندی پردازش سمت کارخواه (CSR) / پردازش سمت سرور را دربرمی‌گیرد. این ابزارها و استراتژی‌ها می‌توانند به بهبود برنامه‌های وب پویایی که با Firebase ساخته شده‌اند و در محیط‌های Google مانند Firebase App Hosting مستقر شده‌اند کمک کنند.

از FirebaseServerApp برای این کارها استفاده کنید:

  • کد سمت سرور را در بافت کاربر اجرا کنید، برخلاف Firebase Admin SDK که حقوق کامل مدیریت دارد.
  • استفاده از «بررسی برنامه» را در محیط‌های SSR فعال کنید.
  • ادامه دادن جلسه Firebase Auth که در کارخواه ایجاد شده است.

چرخه حیات FirebaseServerApp

چارچوب‌های پرداز سمت سرور (SSR) و دیگر زمان‌های اجرای غیرمرورگر مانند کارگران ابری با استفاده مجدد از منابع در چندین اجرا، زمان مقداردهی اولیه را بهینه‌سازی می‌کنند. ‫FirebaseServerApp برای سازگاری با این محیط‌ها بااستفاده از سازوکار شمارش مرجع طراحی شده است. اگر برنامه‌ای initializeServerApp را با پارامترهای مشابه با initializeServerApp قبلی فراخوانی کند، همان نمونه FirebaseServerApp را که قبلاً مقداردهی اولیه شده است دریافت می‌کند. این کار سربار مقداردهی اولیه غیرضروری و تخصیص حافظه را کاهش می‌دهد. وقتی deleteApp در نمونه FirebaseServerApp فراخوانی می‌شود، تعداد ارجاع را کاهش می‌دهد و پس‌از اینکه تعداد ارجاع به صفر رسید، نمونه آزاد می‌شود.

درحال پاک‌سازی FirebaseServerApp نمونه

دانستن اینکه چه زمانی باید deleteApp را در نمونه FirebaseServerApp فراخوانی کرد می‌تواند دشوار باشد، به‌ویژه اگر عملیات ناهمگام زیادی را به‌طور موازی اجرا می‌کنید. فیلد releaseOnDeref در FirebaseServerAppSettings به ساده‌سازی این موضوع کمک می‌کند. اگر 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);
  ...
}

ازسر گرفتن جلسه‌های اصالت‌سنجی‌شده ایجادشده در کارخواه

وقتی نمونه‌ای از FirebaseServerApp با شناسه اصالت‌سنجی مقداردهی اولیه می‌شود، امکان پل زدن جلسه‌های کاربر اصالت‌سنجی‌شده بین محیط‌های پرداخت سمت کارخواه (CSR) و پرداخت سمت سرور (SSR) را فراهم می‌کند. نمونه‌های Firebase Auth SDK که با شیء FirebaseServerApp حاوی Auth ID token مقداردهی اولیه شده‌اند، تلاش می‌کنند کاربر را در مقداردهی اولیه بدون نیاز به فراخوانی روش‌های ورود به سیستم توسط برنامه وارد سیستم کنند.

ارائه یک شناسه Auth ID به برنامه‌ها اجازه می‌دهد از هریک از روش‌های ورود به سیستم 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.

استفاده از «بررسی برنامه» در محیط‌های SSR

اجرای «بررسی برنامه» به نمونه‌ای از «کیت توسعه نرم‌افزار بررسی برنامه» متکی است که «کیت‌های توسعه نرم‌افزار Firebase» برای فراخوانی داخلی getToken از آن استفاده می‌کنند. سپس، رمز حاصل در درخواست‌های ارسال‌شده به همه سرویس‌های Firebase گنجانده می‌شود تا زیرینه بتواند برنامه را اعتبارسنجی کند.

بااین‌حال، چون «کیت توسعه نرم‌افزار App Check» برای دسترسی به اکتشافات خاصی برای اعتبارسنجی برنامه به مرورگر نیاز دارد، نمی‌توان آن را در محیط‌های سرور مقداردهی اولیه کرد.

FirebaseServerApp جایگزینی ارائه می‌دهد. اگر درطول مقداردهی اولیه FirebaseServerApp، یک کد App Check تولیدشده توسط کارخواه ارائه شود، کیت‌های توسعه نرم‌افزار محصول Firebase هنگام فراخوانی سرویس‌های Firebase از آن استفاده خواهند کرد و نیاز به نمونه کیت توسعه نرم‌افزار App Check را ازبین می‌برد.

/// 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 اصالت‌سنجی‌شده (و کدهای App Check) از کارخواه به مرحله پردازش سمت سرور (SSR)، از یک سرویس‌کار استفاده کنید. این رویکرد شامل رهگیری درخواست‌های واکشی است که SSR را راه‌اندازی می‌کنند و توکن‌ها را به سرایندهای درخواست اضافه می‌کنند.

برای پیاده‌سازی مرجع کارگر سرویس Firebase Auth، به مدیریت جلسه با کارگران سرویس مراجعه کنید. همچنین برای کدی که نحوه تجزیه این توکن‌ها از سرصفحه‌ها را برای استفاده در مقداردهی اولیه FirebaseServerApp نشان می‌دهد، به تغییرات سمت سرور مراجعه کنید.

استفاده از Firestore در محیط‌های SSR

هنگام ساختن برنامه‌های وب با «پرداخت سمت سرور» (SSR)، اغلب لازم است داده‌ها را بین سرور و کارخواه هم‌رسانی کنید تا عملکرد و تجربه کاربری را بهینه‌سازی کنید. کیت توسعه نرم‌افزار Firestore ابزارهای سریال‌سازی ارائه می‌دهد که به شما امکان می‌دهد عکس‌های آنی و انواع داده‌های خاص را در سرور ضبط کنید و آن‌ها را مستقیماً به مؤلفه‌های سمت کارخواه خود منتقل کنید. این فرایند با فعال کردن مشتری برای هیدراته کردن حالت بااستفاده از داده‌های پیش‌واکشی‌شده درطول فاز SSR، واکشی‌های زائد را حذف می‌کند. علاوه‌براین، می‌توانید از این حالت‌های سریالی‌شده به شنوندگان هم‌زمان منتقل شوید و مطمئن شوید که برنامه‌تان با پایگاه داده همگام‌سازی‌شده باقی می‌ماند.

این بخش نحوه استفاده مجدد از داده‌های بازیابی‌شده درطول مرحله پردازش سمت سرور (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();

Deserialize Data Types

انواع داده 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، می‌توانید نمونه‌های DocumentSnapshot و QuerySnapshot را بااستفاده از toJSON سریال‌سازی کنید. اما برای غیرسریالی کردن آن‌ها، باید از توابع مستقل documentSnapshotFromJSON و querySnapshotFromJSON به‌جای روش ثابت fromJSON استفاده کنید.

برای مثال، نتایج querySnapshot از عملیات query را می‌توان بااستفاده از روش 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);

شنوندگان با عکس‌های آنی سریالی

اگرچه داده‌های پرس‌وجوشده درطول فاز SSR برای رندر CSR اولیه شما ارزشمند است، ممکن است همچنان نیاز باشد سرویس Firestore را برای به‌روزرسانی‌های هم‌زمان آن اطلاعات نظارت کنید.

اگر برنامه‌تان به این به‌روزرسانی‌های هم‌زمان نیاز دارد، می‌توانید از تابع onSnapshotResume برای مقداردهی اولیه Firestore SnapshotListeners با داده‌های سریالی 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);