แอปที่กำลังใช้ Firebase Web API ที่มีเนมสเปซใดๆ จาก compat
ใช้ร่วมกันได้จนถึงเวอร์ชัน 8 หรือก่อนหน้า ควรพิจารณาย้ายไปยัง API แบบแยกส่วนโดยใช้คำแนะนำในคู่มือนี้
คู่มือนี้จะถือว่าคุณคุ้นเคยกับ API ที่มีเนมสเปซ และคุณจะใช้ประโยชน์จากชุดรวมโมดูล เช่น webpack หรือ Rollup สำหรับการอัปเกรดและการพัฒนาแอปแบบโมดูลาร์อย่างต่อเนื่อง
ขอแนะนำให้ใช้โมดูลบันเดิลในสภาพแวดล้อมการพัฒนาของคุณ หากคุณไม่ได้ใช้ คุณจะไม่สามารถใช้ประโยชน์จากประโยชน์หลักของโมดูลาร์ API ในขนาดแอปที่ลดลง คุณต้องใช้ npm หรือ Yarn เพื่อติดตั้ง SDK
ขั้นตอนการอัปเกรดในคู่มือนี้จะอิงตามเว็บแอปในจินตนาการที่ใช้ Authentication และ Cloud Firestore SDK การทำงานตามตัวอย่างจะช่วยให้คุณเชี่ยวชาญในแนวคิดและขั้นตอนปฏิบัติที่จำเป็นในการอัปเกรด Firebase Web SDK ที่รองรับทั้งหมด
เกี่ยวกับไลบรารีเนมสเปซ ( compat
)
มีไลบรารีสองประเภทสำหรับ Firebase Web SDK:
- แบบแยกส่วน - พื้นผิว API ใหม่ที่ออกแบบมาเพื่ออำนวยความสะดวกในการเขย่าต้นไม้ (ลบโค้ดที่ไม่ได้ใช้) เพื่อทำให้เว็บแอปของคุณมีขนาดเล็กและรวดเร็วที่สุด
- เนมสเปซ (
compat
) - พื้นผิว API ที่คุ้นเคยซึ่งเข้ากันได้อย่างสมบูรณ์กับ SDK เวอร์ชันก่อนหน้า ทำให้คุณสามารถอัปเกรดได้โดยไม่ต้องเปลี่ยนโค้ด Firebase ทั้งหมดในคราวเดียว ไลบรารีที่เข้ากันได้มีข้อได้เปรียบด้านขนาดหรือประสิทธิภาพเพียงเล็กน้อยหรือไม่มีเลยเหนือคู่หูที่มีเนมสเปซ
คู่มือนี้จะอนุมานว่าคุณจะใช้ประโยชน์จากไลบรารีที่เข้ากันได้เพื่ออำนวยความสะดวกในการอัปเกรดของคุณ ไลบรารีเหล่านี้อนุญาตให้คุณใช้โค้ดเนมสเปซต่อไปควบคู่ไปกับโค้ดที่ปรับโครงสร้างใหม่สำหรับโมดูลาร์ API ซึ่งหมายความว่าคุณสามารถคอมไพล์และดีบักแอปของคุณได้ง่ายขึ้นขณะที่คุณทำงานผ่านกระบวนการอัปเกรด
สำหรับแอปที่มีการเปิดเผย Firebase Web SDK น้อยมาก ตัวอย่างเช่น แอปที่เรียกใช้ API การตรวจสอบสิทธิ์อย่างง่ายเท่านั้น การปรับโครงสร้างโค้ดเนมสเปซที่เก่ากว่าโดยไม่ใช้ไลบรารีที่เข้ากันได้อาจทำได้จริง หากคุณกำลังอัปเกรดแอปดังกล่าว คุณสามารถทำตามคำแนะนำในคู่มือนี้สำหรับ "โมดูล API" โดยไม่ต้องใช้ไลบรารีที่เข้ากันได้
เกี่ยวกับกระบวนการอัปเกรด
แต่ละขั้นตอนของกระบวนการอัปเกรดได้รับการกำหนดขอบเขตเพื่อให้คุณสามารถแก้ไขซอร์สสำหรับแอปของคุณให้เสร็จ จากนั้นจึงคอมไพล์และรันโดยไม่ทำให้แอปเสียหาย โดยสรุป สิ่งที่คุณต้องทำเพื่ออัปเกรดแอปมีดังนี้
- เพิ่มไลบรารีโมดูลาร์และไลบรารีที่เข้ากันได้ในแอปของคุณ
- อัปเดตคำสั่งการนำเข้าในโค้ดของคุณเพื่อให้เข้ากันได้
- โค้ด Refactor สำหรับผลิตภัณฑ์เดียว (เช่น การพิสูจน์ตัวตน) เป็นสไตล์โมดูลาร์
- ทางเลือก: ณ จุดนี้ ให้ลบไลบรารีที่เข้ากันได้กับการตรวจสอบสิทธิ์และรหัสที่เข้ากันได้สำหรับการตรวจสอบสิทธิ์ เพื่อให้ตระหนักถึงประโยชน์ขนาดแอปสำหรับการตรวจสอบสิทธิ์ก่อนดำเนินการต่อ
- ฟังก์ชัน Refactor สำหรับแต่ละผลิตภัณฑ์ (เช่น Cloud Firestore, FCM เป็นต้น) ให้เป็นรูปแบบโมดูลาร์ คอมไพล์และทดสอบจนครบทุกส่วน
- อัปเดตรหัสเริ่มต้นเป็นรูปแบบโมดูลาร์
- ลบคำสั่งการทำงานร่วมกันที่เหลือทั้งหมดและโค้ดที่เข้ากันได้ออกจากแอปของคุณ
รับ SDK เวอร์ชันล่าสุด
ในการเริ่มต้น ให้รับไลบรารีโมดูลาร์และไลบรารีที่เข้ากันได้โดยใช้ npm:
npm i firebase@10.3.1 # OR yarn add firebase@10.3.1
อัปเดตการนำเข้าให้เข้ากันได้
เพื่อให้รหัสของคุณทำงานต่อไปหลังจากอัปเดตการอ้างอิงของคุณ ให้เปลี่ยนคำสั่งการนำเข้าของคุณเพื่อใช้เวอร์ชัน "เข้ากันได้" ของการนำเข้าแต่ละครั้ง ตัวอย่างเช่น:
ก่อนหน้า: เวอร์ชัน 8 หรือก่อนหน้า
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
หลังจาก: เข้ากันได้
// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
ปรับโครงสร้างใหม่ให้เป็นรูปแบบโมดูลาร์
แม้ว่าเนมสเปซ API จะอิงตามเนมสเปซแบบดอทเชนและรูปแบบบริการ วิธีการแบบโมดูลาร์หมายความว่าโค้ดของคุณจะถูกจัดระเบียบตาม ฟังก์ชันต่างๆ เป็นหลัก ใน API แบบโมดูลาร์ แพ็กเกจ firebase/app
และแพ็กเกจอื่นๆ จะไม่ส่งคืนการส่งออกแบบครอบคลุมที่มีเมธอดทั้งหมดจากแพ็กเกจ แพ็กเกจจะส่งออกฟังก์ชันแต่ละรายการแทน
ใน API แบบแยกส่วน บริการจะถูกส่งผ่านเป็นอาร์กิวเมนต์แรก จากนั้นฟังก์ชันจะใช้รายละเอียดของบริการเพื่อดำเนินการส่วนที่เหลือ มาดูวิธีการทำงานในสองตัวอย่างที่รีแฟคเตอร์การเรียกไปยัง Authentication และ Cloud Firestore API
ตัวอย่างที่ 1: refactoring ฟังก์ชันการรับรองความถูกต้อง
ก่อน: เข้ากันได้
รหัสที่เข้ากันได้จะเหมือนกับรหัสเนมสเปซ แต่การนำเข้ามีการเปลี่ยนแปลง
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
const auth = firebase.auth();
auth.onAuthStateChanged(user => {
// Check for user status
});
หลัง: แบบแยกส่วน
ฟังก์ชัน getAuth
รับ firebaseApp
เป็นพารามิเตอร์ตัวแรก ฟังก์ชัน onAuthStateChanged
ไม่ได้ถูกโยงจากอินสแตนซ์การตรวจสอบ auth
เนื่องจากจะเป็นใน API แบบเนมสเปซ แต่เป็นฟังก์ชันฟรีที่ใช้ auth
เป็นพารามิเตอร์ตัวแรก
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
// Check for user status
});
อัปเดตการจัดการวิธีการรับรองความถูก getRedirectResult
API แบบโมดูลาร์แนะนำการเปลี่ยนแปลงแบบสมบูรณ์ใน getRedirectResult
เมื่อไม่มีการเรียกใช้การดำเนินการเปลี่ยนเส้นทาง API แบบโมดูลาร์จะส่งคืน null
ซึ่งตรงข้ามกับ API ที่มีเนมสเปซ ซึ่งส่งคืน UserCredential
พร้อมผู้ใช้ null
ก่อน: เข้ากันได้
const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
return null;
}
return result;
หลัง: แบบแยกส่วน
const result = await getRedirectResult(auth);
// Provider of the access token could be Facebook, Github, etc.
if (result === null || provider.credentialFromResult(result) === null) {
return null;
}
return result;
ตัวอย่างที่ 2: การปรับโครงสร้างฟังก์ชัน Cloud Firestore
ก่อน: เข้ากันได้
import "firebase/compat/firestore"
const db = firebase.firestore();
db.collection("cities").where("capital", "==", true)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
หลัง: แบบแยกส่วน
ฟังก์ชัน getFirestore
ใช้ firebaseApp
เป็นพารามิเตอร์ตัวแรก ซึ่งส่งคืนจาก initializeApp
ในตัวอย่างก่อนหน้านี้ โปรดทราบว่าโค้ดสำหรับสร้างคิวรีนั้นแตกต่างกันมากใน API แบบโมดูลาร์อย่างไร ไม่มีการผูกมัด และเมธอดต่างๆ เช่น query
หรือ where
ตอนนี้ถูกเปิดเผยเป็นฟังก์ชันฟรี
import { getFirestore, collection, query, where, getDocs } from "firebase/firestore";
const db = getFirestore(firebaseApp);
const q = query(collection(db, "cities"), where("capital", "==", true));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
อัปเดตการอ้างอิงถึง Firestore DocumentSnapshot.exists
API แบบโมดูลาร์แนะนำการเปลี่ยนแปลงที่ทำลายซึ่งคุณสมบัติ firestore.DocumentSnapshot.exists
ถูกเปลี่ยนเป็น เมธอด โดยพื้นฐานแล้วการทำงานจะเหมือนกัน (ทดสอบว่ามีเอกสารอยู่หรือไม่) แต่คุณต้องปรับโครงสร้างรหัสของคุณใหม่เพื่อใช้วิธีการที่ใหม่กว่าดังที่แสดง:
ก่อน:เข้ากันได้
if (snapshot.exists) {
console.log("the document exists");
}
หลัง: แบบแยกส่วน
if (snapshot.exists()) {
console.log("the document exists");
}
ตัวอย่างที่ 3: การรวมสไตล์โค้ดเนมสเปซและโมดูลาร์
การใช้ไลบรารีที่เข้ากันได้ระหว่างการอัปเกรดทำให้คุณสามารถใช้โค้ดเนมสเปซต่อไปได้ควบคู่ไปกับโค้ดที่ปรับโครงสร้างใหม่สำหรับโมดูลาร์ API ซึ่งหมายความว่าคุณสามารถเก็บโค้ดเนมสเปซที่มีอยู่สำหรับ Cloud Firestore ในขณะที่คุณเปลี่ยนโครงสร้างการตรวจสอบสิทธิ์หรือโค้ด Firebase SDK อื่นๆ เป็นสไตล์โมดูลาร์ และยังคงคอมไพล์แอปของคุณด้วยโค้ดทั้งสองสไตล์ได้สำเร็จ เช่นเดียวกับโค้ด API แบบเนมสเปซและโมดูลาร์ ภายใน ผลิตภัณฑ์ เช่น Cloud Firestore สไตล์โค้ดใหม่และเก่าสามารถอยู่ร่วมกันได้ ตราบใดที่คุณนำเข้าแพ็คเกจที่เข้ากันได้:
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import { getDoc } from 'firebase/firestore'
const docRef = firebase.firestore().doc();
getDoc(docRef);
โปรดทราบว่าแม้ว่าแอปของคุณจะคอมไพล์ แต่คุณจะไม่ได้รับประโยชน์จากขนาดแอปของโค้ดโมดูลาร์จนกว่าคุณจะลบคำสั่งและโค้ดที่เข้ากันได้ทั้งหมดออกจากแอปของคุณ
อัปเดตรหัสเริ่มต้น
อัปเดตโค้ดเริ่มต้นของแอปเพื่อใช้ไวยากรณ์แบบแยกส่วน สิ่งสำคัญคือต้องอัปเดตโค้ดนี้ หลังจากที่ คุณปรับโครงสร้างโค้ดทั้งหมดในแอปเรียบร้อยแล้ว นี่เป็นเพราะ firebase.initializeApp()
เริ่มต้นสถานะส่วนกลางสำหรับทั้ง API ที่เข้ากันได้และแบบโมดูลาร์ ในขณะที่ฟังก์ชัน initializeApp()
แบบโมดูลาร์จะเริ่มต้นเฉพาะสถานะสำหรับโมดูลาร์เท่านั้น
ก่อน: เข้ากันได้
import firebase from "firebase/compat/app"
firebase.initializeApp({ /* config */ });
หลัง: แบบแยกส่วน
import { initializeApp } from "firebase/app"
const firebaseApp = initializeApp({ /* config */ });
ลบรหัสที่เข้ากันได้
เพื่อให้ทราบถึงประโยชน์ด้านขนาดของ API แบบโมดูลาร์ ในที่สุดคุณควรแปลงการเรียกใช้ทั้งหมดเป็นรูปแบบโมดูลาร์ที่แสดงด้านบน และลบคำสั่ง import "firebase/compat/*
ทั้งหมดออกจากโค้ดของคุณ เมื่อคุณทำเสร็จแล้ว ไม่ควรมีการอ้างอิงอีกต่อไป ไปยัง firebase.*
global namespace หรือโค้ดอื่นๆ ในรูปแบบ namespaced API
ใช้ไลบรารีที่เข้ากันได้จากหน้าต่าง
API แบบแยกส่วนได้รับการปรับให้ทำงานร่วมกับโมดูลมากกว่าวัตถุ window
ของเบราว์เซอร์ ไลบรารีเวอร์ชันก่อนหน้าอนุญาตให้โหลดและจัดการ Firebase โดยใช้เนมสเปซ window.firebase
ไม่แนะนำให้ทำต่อไปเนื่องจากไม่อนุญาตให้มีการกำจัดรหัสที่ไม่ได้ใช้ อย่างไรก็ตาม JavaScript SDK เวอร์ชันที่เข้ากันได้จะทำงานร่วมกับ window
สำหรับนักพัฒนาที่ไม่ต้องการเริ่มเส้นทางการอัปเกรดโมดูลาร์ในทันที
<script src="https://www.gstatic.com/firebasejs/10.3.1/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.3.1/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.3.1/firebase-auth-compat.js"></script>
<script>
const firebaseApp = firebase.initializeApp({ /* Firebase config */ });
const db = firebaseApp.firestore();
const auth = firebaseApp.auth();
</script>
ไลบรารีความเข้ากันได้ใช้รหัสโมดูลาร์ภายใต้ประทุนและจัดเตรียม API เดียวกันกับ API ที่มีเนมสเปซ ซึ่งหมายความว่าคุณสามารถดู การอ้างอิง API แบบเนมสเปซ และข้อมูลโค้ดเนมสเปซสำหรับรายละเอียด วิธีนี้ไม่แนะนำให้ใช้ในระยะยาว แต่เป็นการเริ่มอัปเกรดเป็นไลบรารีโมดูลาร์เต็มรูปแบบ
ประโยชน์และข้อจำกัดของโมดูลาร์ SDK
SDK ที่ปรับให้เป็นโมดูลอย่างสมบูรณ์มีข้อดีเหล่านี้เหนือเวอร์ชันก่อนหน้า:
- SDK แบบแยกส่วนช่วยให้ขนาดแอปลดลงอย่างมาก ใช้รูปแบบโมดูล JavaScript ที่ทันสมัย ทำให้สามารถ "เขย่าต้นไม้" ซึ่งคุณนำเข้าเฉพาะสิ่งประดิษฐ์ที่แอปของคุณต้องการ ขึ้นอยู่กับแอปของคุณ การเขย่าต้นไม้ด้วย SDK แบบโมดูลาร์อาจส่งผลให้มีกิโลไบต์น้อยกว่าแอปที่เทียบเคียงได้ซึ่งสร้างโดยใช้ Namespaced API ถึง 80% ทั้งนี้ขึ้นอยู่กับแอปของคุณ
- SDK แบบแยกส่วนจะยังคงได้รับประโยชน์จากการพัฒนาคุณลักษณะอย่างต่อเนื่อง ในขณะที่ API ที่มีเนมสเปซจะไม่ได้รับประโยชน์