إذا كنت قد عملت مع حزمة تطوير البرامج (SDK) لمنصة Firebase بلغة JavaScript أو حِزم تطوير البرامج (SDK) الأخرى الخاصة بالعملاء في Firebase، من المحتمل أنّك على دراية بواجهة FirebaseApp وكيفية استخدامها لإعداد مثيلات التطبيقات. لتسهيل العمليات المشابهة على الخادم، توفّر Firebase FirebaseServerApp.
FirebaseServerApp هو نوع من FirebaseApp يُستخدم في بيئات العرض من جهة الخادم (SSR). وتتضمّن أدوات لمواصلة جلسات Firebase التي تمتد على مستوى العرض من جهة العميل (CSR) والعرض من جهة الخادم. يمكن أن تساعد هذه الأدوات والاستراتيجيات في تحسين تطبيقات الويب الديناميكية التي تم إنشاؤها باستخدام Firebase ونشرها في بيئات Google، مثل Firebase App Hosting.
يمكنك استخدام FirebaseServerApp لإجراء ما يلي:
- تنفيذ الرمز البرمجي من جهة الخادم ضمن سياق المستخدم، وذلك على عكس مدير SDK في Firebase الذي يملك حقوق إدارة كاملة.
- فعِّل استخدام فحص التطبيقات في بيئات SSR.
- مواصلة جلسة Firebase Auth تم إنشاؤها في العميل
مراحل نشاط FirebaseServerApp
تعمل أُطر العرض من جهة الخادم (SSR) وأوقات التشغيل الأخرى غير المتوافقة مع المتصفح، مثل مشغّلي السحابة الإلكترونية، على تحسين وقت التهيئة من خلال إعادة استخدام الموارد في عمليات تنفيذ متعددة. تم تصميم FirebaseServerApp لاستيعاب هذه البيئات من خلال استخدام آلية احتساب مرجعية. إذا استدعى تطبيق initializeServerApp بالمعلمات نفسها التي تم استخدامها في استدعاء سابق، سيتلقّى مثيل FirebaseServerApp نفسه الذي تم إعداده مسبقًا.initializeServerApp يؤدي ذلك إلى تقليل الحِمل الزائد غير الضروري لعملية التهيئة
وعمليات تخصيص الذاكرة. عند استدعاء 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). ستحاول مثيلات حزمة تطوير البرامج (SDK) الخاصة بخدمة Firebase Auth التي تمّت تهيئتها باستخدام عنصر FirebaseServerApp يحتوي على رمز مميّز لمعرّف 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
يعتمد فرض استخدام App Check على مثيل حزمة تطوير البرامج (SDK) الخاصة بخدمة App Check التي تستخدمها حِزم تطوير البرامج (SDK) من Firebase لإجراء طلبات داخلية إلى getToken. بعد ذلك، يتم تضمين الرمز المميز الناتج في الطلبات
إلى جميع خدمات Firebase، ما يسمح للخلفية بالتحقّق من صحة التطبيق.
ومع ذلك، بما أنّ حزمة تطوير البرامج (SDK) الخاصة بخدمة فحص التطبيقات تحتاج إلى متصفّح للوصول إلى إحصاءات استدلالية معيّنة من أجل التحقّق من صحة التطبيق، لا يمكن تهيئتها في بيئات الخادم.
تقدّم السمة FirebaseServerApp بديلاً. في حال توفير رمز مميّز من فحص التطبيقات تم إنشاؤه من جهة العميل أثناء عملية تهيئة FirebaseServerApp، ستستخدم حِزم SDK الخاصة بمنتجات Firebase هذا الرمز عند استدعاء خدمات Firebase، ما يلغي الحاجة إلى مثيل لحزمة تطوير البرامج (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 المميزة التي تمت المصادقة عليها (ورموز فحص التطبيقات المميزة) من العميل إلى مرحلة العرض من جهة الخادم (SSR)، استخدِم مشغّل الخدمات. يتضمّن هذا الأسلوب اعتراض طلبات الجلب التي تؤدي إلى تشغيل SSR وإلحاق الرموز المميزة بعناوين الطلبات.
راجِع إدارة الجلسات باستخدام عاملي الخدمة للحصول على نموذج تنفيذ لبرنامج عامل خدمة في "مصادقة Firebase". اطّلِع أيضًا على التغييرات على جهة الخادم للحصول على رمز يوضّح كيفية تحليل هذه الرموز المميّزة من العناوين لاستخدامها في عملية تهيئة FirebaseServerApp.
استخدام Firestore في بيئات SSR
عند إنشاء تطبيقات ويب باستخدام العرض من جهة الخادم (SSR)، غالبًا ما تحتاج إلى مشاركة البيانات بين الخادم والعميل لتحسين الأداء وتجربة المستخدم. توفّر حزمة تطوير البرامج (SDK) الخاصة بـ Firestore أدوات تسلسل تتيح لك التقاط لقطات وأنواع بيانات معيّنة على الخادم وتمريرها مباشرةً إلى مكوّناتك من جهة العميل. تؤدي هذه العملية إلى إلغاء عمليات الجلب المكرّرة من خلال السماح للعميل بتعبئة الحالة باستخدام البيانات التي تم جلبها مسبقًا أثناء مرحلة العرض من جهة الخادم. بالإضافة إلى ذلك، يمكنك الانتقال من حالات التسلسل هذه إلى أدوات معالجة في الوقت الفعلي، ما يضمن بقاء تطبيقك متزامنًا مع قاعدة البيانات.
يوضّح هذا القسم كيفية إعادة استخدام البيانات التي تم استرجاعها أثناء مرحلة العرض من جهة الخادم (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، يمكنك تسلسل مثيلات 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);
المستمعون الذين لديهم "لقطات متسلسلة"
على الرغم من أنّ البيانات التي يتم طلبها خلال مرحلة العرض من جهة الخادم تكون قيّمة لعملية العرض الأوّلية من جهة العميل، قد تحتاج إلى مراقبة خدمة Firestore للحصول على آخر المعلومات في الوقت الفعلي.
إذا كان تطبيقك يتطلّب هذه التعديلات في الوقت الفعلي، يمكنك استخدام الدالة onSnapshotResume
لإعداد SnapshotListeners في Firestore باستخدام بيانات 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);