หากเคยใช้ Firebase JS SDK หรือ Firebase Client SDK อื่นๆ คุณอาจคุ้นเคยกับอินเทอร์เฟซ FirebaseApp และวิธีใช้เพื่อกำหนดค่าอินสแตนซ์ของแอป Firebase มี FirebaseServerApp เพื่ออำนวยความสะดวกในการดำเนินการที่คล้ายกันในฝั่งเซิร์ฟเวอร์
FirebaseServerApp เป็นตัวแปรของ FirebaseApp สำหรับใช้ในสภาพแวดล้อมการแสดงผลฝั่งเซิร์ฟเวอร์ (SSR) ซึ่งรวมถึงเครื่องมือในการดำเนินการเซสชัน Firebase ต่อไป
ที่ครอบคลุมการแสดงผลฝั่งไคลเอ็นต์ (CSR) / การแสดงผลฝั่งเซิร์ฟเวอร์ เครื่องมือและกลยุทธ์เหล่านี้ช่วยปรับปรุงเว็บแอปแบบไดนามิกที่สร้างด้วย Firebase และ
ติดตั้งใช้งานในสภาพแวดล้อมของ Google เช่น Firebase App Hosting ได้
ใช้ FirebaseServerApp เพื่อทำสิ่งต่อไปนี้
- เรียกใช้โค้ดฝั่งเซิร์ฟเวอร์ภายในบริบทของผู้ใช้ ซึ่งแตกต่างจาก Firebase Admin SDK ที่มีสิทธิ์การดูแลระบบเต็มรูปแบบ
- เปิดใช้ App Check ในสภาพแวดล้อม SSR
- ดำเนินการต่อในเซสชัน Firebase Auth ที่สร้างในไคลเอ็นต์
วงจรการใช้งาน FirebaseServerApp
เฟรมเวิร์กการแสดงผลฝั่งเซิร์ฟเวอร์ (SSR) และรันไทม์อื่นๆ ที่ไม่ใช่เบราว์เซอร์ เช่น Cloud Worker จะเพิ่มประสิทธิภาพเวลาเริ่มต้นโดยการนำทรัพยากรกลับมาใช้ใหม่ในการดำเนินการหลายครั้ง FirebaseServerApp ออกแบบมาเพื่อรองรับสภาพแวดล้อมเหล่านี้
โดยใช้กลไกการนับอ้างอิง หากแอปเรียกใช้
initializeServerApp ด้วยพารามิเตอร์เดียวกันกับ
initializeServerApp ก่อนหน้า แอปจะได้รับอินสแตนซ์ FirebaseServerApp เดียวกันกับที่
เริ่มต้นไว้แล้ว ซึ่งจะช่วยลดโอเวอร์เฮดในการเริ่มต้นที่ไม่จำเป็น
และการจัดสรรหน่วยความจำ เมื่อเรียกใช้ deleteApp ในอินสแตนซ์ FirebaseServerApp
ระบบจะลดจำนวนการอ้างอิง และจะปล่อยอินสแตนซ์หลังจากที่
จำนวนการอ้างอิงเป็น 0
การล้างข้อมูลอินสแตนซ์ 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 จะพยายามลงชื่อเข้าใช้ผู้ใช้เมื่อเริ่มต้นโดยไม่ต้องให้แอปพลิเคชันเรียกใช้เมธอดการลงชื่อเข้าใช้ใดๆ
การระบุโทเค็นรหัสการให้สิทธิ์จะช่วยให้แอปใช้วิธีการลงชื่อเข้าใช้ของ 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 ในสภาพแวดล้อม SSR
การบังคับใช้ App Check จะขึ้นอยู่กับอินสแตนซ์ App Check SDK ที่ Firebase SDK ใช้
เพื่อเรียก getToken ภายใน จากนั้นระบบจะรวมโทเค็นที่ได้ไว้ในคำขอ
ไปยังบริการทั้งหมดของ Firebase เพื่อให้แบ็กเอนด์ตรวจสอบแอปได้
อย่างไรก็ตาม เนื่องจาก App Check SDK ต้องใช้เบราว์เซอร์เพื่อเข้าถึงฮิวริสติกที่เฉพาะเจาะจง สำหรับการตรวจสอบแอป จึงเริ่มต้นในสภาพแวดล้อมของเซิร์ฟเวอร์ไม่ได้
FirebaseServerApp มีทางเลือกให้ หากมีการระบุโทเค็น App Check
ที่ไคลเอ็นต์สร้างขึ้นในระหว่างFirebaseServerAppการเริ่มต้น SDK ของผลิตภัณฑ์ Firebase จะใช้โทเค็นดังกล่าวเมื่อเรียกใช้บริการ Firebase ซึ่งจะช่วยลดความจำเป็น
ในการใช้อินสแตนซ์ 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.
ส่งโทเค็นไคลเอ็นต์ไปยังระยะการแสดงผลฝั่งเซิร์ฟเวอร์
หากต้องการส่งโทเค็นรหัสการตรวจสอบสิทธิ์ที่ได้รับการตรวจสอบสิทธิ์ (และโทเค็น App Check) จากไคลเอ็นต์ ไปยังเฟสการแสดงผลฝั่งเซิร์ฟเวอร์ (SSR) ให้ใช้ Service Worker แนวทางนี้ เกี่ยวข้องกับการสกัดกั้นคำขอ Fetch ที่ทริกเกอร์ SSR และต่อท้ายโทเค็น ในส่วนหัวของคำขอ
ดูการใช้งานอ้างอิงของ Service Worker ของ Firebase Auth ได้ที่การจัดการเซสชันด้วย Service Worker ดูการเปลี่ยนแปลงฝั่งเซิร์ฟเวอร์สำหรับโค้ด
ที่แสดงวิธีแยกวิเคราะห์โทเค็นเหล่านี้จากส่วนหัวเพื่อใช้ในการเริ่มต้นFirebaseServerApp
ใช้ Firestore ในสภาพแวดล้อม SSR
เมื่อสร้างเว็บแอปพลิเคชันด้วยการแสดงผลฝั่งเซิร์ฟเวอร์ (SSR) คุณมักจะต้อง แชร์ข้อมูลระหว่างเซิร์ฟเวอร์กับไคลเอ็นต์เพื่อเพิ่มประสิทธิภาพและประสบการณ์ของผู้ใช้ Firestore SDK มีเครื่องมือการซีเรียลไลซ์ที่ช่วยให้คุณ บันทึกสแนปชอตและประเภทข้อมูลที่เฉพาะเจาะจงในเซิร์ฟเวอร์ และส่งไปยังคอมโพเนนต์ฝั่งไคลเอ็นต์ได้โดยตรง กระบวนการนี้จะช่วยลดการดึงข้อมูลที่ซ้ำซ้อนโดย อนุญาตให้ไคลเอ็นต์ไฮเดรตสถานะโดยใช้ข้อมูลที่ดึงข้อมูลล่วงหน้าในระหว่างระยะ 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();
ยกเลิกการซีเรียลไลซ์ประเภทข้อมูล
ประเภทข้อมูล Firestore มีเมธอดแบบคงที่ fromJSON เพื่อแปลงข้อมูลที่
ทำให้เป็นอนุกรมเป็นประเภทข้อมูล Firestore ที่ใช้งานได้
เช่น ตัวอย่างต่อไปนี้จะยกเลิกการซีเรียลไลซ์Bytesประเภทข้อมูล
import {
Bytes
} from 'firebase/firestore';
// Assuming the same `bytesJSON` variable from the previous example.
const deserializedBytes = Bytes.fromJSON(bytesJSON);
แปลงอนุกรมและยกเลิกการแปลงอนุกรมของสแนปชอต Firestore
คุณสามารถจัดรูปแบบอินสแตนซ์ของ
DocumentSnapshotและ QuerySnapshot โดยใช้ toJSON ได้เช่นเดียวกับประเภทข้อมูล Firestore อย่างไรก็ตาม หากต้องการยกเลิกการซีเรียลไลซ์
คุณต้องใช้ฟังก์ชันแบบสแตนด์อโลน 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
เพื่อเริ่มต้น SnapshotListenerFirestore ด้วยข้อมูล 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);