อัปเกรดจาก API เนมสเปซเป็น API แบบโมดูลาร์

ปัจจุบันแอปที่ใช้ Firebase Web API แบบเนมสเปซ ตั้งแต่ไลบรารี compat กันได้จนถึงเวอร์ชัน 8 หรือก่อนหน้า ควรพิจารณาย้ายไปยัง API แบบโมดูลาร์โดยใช้คำแนะนำในคู่มือนี้

คู่มือนี้จะถือว่าคุณคุ้นเคยกับเนมสเปซ API และคุณจะใช้ประโยชน์จากชุดรวมโมดูล เช่น webpack หรือ Rollup สำหรับการอัปเกรดและการพัฒนาแอปโมดูลาร์ที่กำลังดำเนินอยู่

แนะนำให้ใช้ตัวรวมโมดูลในสภาพแวดล้อมการพัฒนาของคุณ หากคุณไม่ได้ใช้ คุณจะไม่สามารถใช้ประโยชน์จากประโยชน์หลักของ Modular API ในขนาดแอปที่ลดลงได้ คุณจะต้องมี npm หรือ เส้นด้าย เพื่อติดตั้ง SDK

ขั้นตอนการอัปเกรดในคู่มือนี้จะอิงตามเว็บแอปจินตภาพที่ใช้ Authentication และ Cloud Firestore SDK การทำงานตามตัวอย่างเหล่านี้จะช่วยให้คุณเชี่ยวชาญแนวคิดและขั้นตอนการปฏิบัติที่จำเป็นในการอัปเกรด Firebase Web SDK ที่รองรับทั้งหมด

เกี่ยวกับไลบรารีเนมสเปซ ( compat )

มีไลบรารีสองประเภทสำหรับ Firebase Web SDK:

  • โมดูลาร์ - พื้นผิว API ใหม่ที่ออกแบบมาเพื่ออำนวยความสะดวกในการเขย่าต้นไม้ (การลบโค้ดที่ไม่ได้ใช้) เพื่อทำให้แอปพลิเคชันเว็บของคุณมีขนาดเล็กและรวดเร็วที่สุด
  • เนมสเปซ ( compat ) - พื้นผิว API ที่คุ้นเคยซึ่งสามารถใช้งานร่วมกับ SDK เวอร์ชันก่อนหน้าได้อย่างสมบูรณ์ ทำให้คุณสามารถอัปเกรดได้โดยไม่ต้องเปลี่ยนโค้ด Firebase ทั้งหมดพร้อมกัน ไลบรารีที่เข้ากันได้มีข้อได้เปรียบด้านขนาดหรือประสิทธิภาพเพียงเล็กน้อยหรือไม่มีเลยเมื่อเทียบกับไลบรารีที่มีเนมสเปซ

คู่มือนี้ถือว่าคุณจะใช้ประโยชน์จากไลบรารีที่เข้ากันได้เพื่ออำนวยความสะดวกในการอัปเกรดของคุณ ไลบรารีเหล่านี้ช่วยให้คุณใช้โค้ดเนมสเปซต่อไปได้ควบคู่ไปกับโค้ดที่ปรับโครงสร้างใหม่สำหรับ API แบบโมดูลาร์ ซึ่งหมายความว่าคุณสามารถคอมไพล์และดีบักแอปของคุณได้ง่ายขึ้นในขณะที่คุณดำเนินการตามกระบวนการอัปเกรด

สำหรับแอปที่มีความเสี่ยงน้อยมากต่อ Firebase Web SDK ตัวอย่างเช่น แอปที่เรียกใช้ API การตรวจสอบสิทธิ์แบบธรรมดา อาจเป็นประโยชน์ในการปรับโครงสร้างโค้ดเนมสเปซเก่าโดยไม่ต้องใช้ไลบรารีที่เข้ากันได้ หากคุณกำลังอัปเกรดแอปดังกล่าว คุณสามารถทำตามคำแนะนำในคู่มือนี้สำหรับ "modular API" ได้โดยไม่ต้องใช้ไลบรารีที่เข้ากันได้

เกี่ยวกับกระบวนการอัปเกรด

แต่ละขั้นตอนของกระบวนการอัปเกรดมีการกำหนดขอบเขตเพื่อให้คุณสามารถแก้ไขซอร์สสำหรับแอปของคุณให้เสร็จสิ้น จากนั้นคอมไพล์และเรียกใช้โดยไม่มีการเสียหาย โดยสรุป นี่คือสิ่งที่คุณจะทำเพื่ออัปเกรดแอป:

  1. เพิ่มไลบรารีโมดูลาร์และไลบรารีที่เข้ากันได้ลงในแอปของคุณ
  2. อัปเดตคำสั่งการนำเข้าในโค้ดของคุณเพื่อใช้งานร่วมกัน
  3. รหัส Refactor สำหรับผลิตภัณฑ์เดียว (เช่น การรับรองความถูกต้อง) ให้เป็นสไตล์โมดูลาร์
  4. ทางเลือก: ณ จุดนี้ ให้ลบไลบรารีความเข้ากันได้ของ Authentication และโค้ด compat สำหรับ Authentication เพื่อให้ทราบถึงประโยชน์ของขนาดแอปสำหรับ Authentication ก่อนดำเนินการต่อ
  5. ปรับโครงสร้างฟังก์ชันสำหรับแต่ละผลิตภัณฑ์ (เช่น Cloud Firestore, FCM ฯลฯ) ให้เป็นสไตล์โมดูลาร์ คอมไพล์และทดสอบจนกว่าทุกพื้นที่จะเสร็จสมบูรณ์
  6. อัปเดตโค้ดการเริ่มต้นเป็นรูปแบบโมดูลาร์
  7. ลบคำสั่ง compat และรหัส compat ที่เหลือทั้งหมดออกจากแอปของคุณ

รับ SDK เวอร์ชันล่าสุด

ในการเริ่มต้น ให้รับไลบรารีโมดูลาร์และไลบรารีที่เข้ากันได้โดยใช้ npm:

npm i firebase@10.8.1

# OR

yarn add firebase@10.8.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: การปรับโครงสร้างฟังก์ชันการรับรองความถูกต้องใหม่

ก่อน: เข้ากันได้

รหัสที่เข้ากันได้จะเหมือนกับรหัสเนมสเปซ แต่การนำเข้ามีการเปลี่ยนแปลง

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() เริ่มต้นสถานะโกลบอลสำหรับทั้ง Compat และ API แบบโมดูลาร์ ในขณะที่ฟังก์ชัน Modular initializeApp() เริ่มต้นเฉพาะสถานะสำหรับโมดูลาร์

ก่อน: เข้ากันได้

import firebase from "firebase/compat/app"

firebase.initializeApp({ /* config */ });

หลัง: แบบแยกส่วน

import { initializeApp } from "firebase/app"

const firebaseApp = initializeApp({ /* config */ });

ลบรหัสความเข้ากันได้

เพื่อให้ทราบถึงคุณประโยชน์ด้านขนาดของ API แบบโมดูลาร์ ในที่สุดคุณควรแปลงการเรียกใช้ทั้งหมดเป็นรูปแบบโมดูลาร์ที่แสดงด้านบน และลบคำสั่ง import "firebase/compat/* ทั้งหมดออกจากโค้ดของคุณ เมื่อเสร็จแล้ว ไม่ควรมีการอ้างอิงอีกต่อไป ไปยัง firebase.* เนมสเปซส่วนกลางหรือโค้ดอื่นใดในรูปแบบ API เนมสเปซ

การใช้ไลบรารี compat จากหน้าต่าง

API แบบโมดูลาร์ได้รับการปรับปรุงให้ทำงานกับโมดูลแทนที่จะเป็นออบเจ็กต์ window ของเบราว์เซอร์ ไลบรารีเวอร์ชันก่อนหน้านี้อนุญาตให้โหลดและจัดการ Firebase โดยใช้เนมสเปซ window.firebase ไม่แนะนำให้ดำเนินการต่อเนื่องจากจะไม่อนุญาตให้มีการกำจัดโค้ดที่ไม่ได้ใช้ อย่างไรก็ตาม JavaScript SDK เวอร์ชันที่เข้ากันได้จะใช้งานได้กับ window สำหรับนักพัฒนาที่ไม่ต้องการเริ่มเส้นทางการอัพเกรดแบบโมดูลาร์ทันที

<script src="https://www.gstatic.com/firebasejs/10.8.1/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.8.1/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.8.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 แบบโมดูลาร์อาจทำให้มีกิโลไบต์น้อยกว่าแอปที่เปรียบเทียบกันได้ซึ่งสร้างโดยใช้ API เนมสเปซถึง 80% ทั้งนี้ขึ้นอยู่กับแอปของคุณ
  • SDK แบบโมดูลาร์จะยังคงได้รับประโยชน์จากการพัฒนาฟีเจอร์ที่กำลังดำเนินอยู่ ในขณะที่ API แบบเนมสเปซจะไม่ได้รับประโยชน์