بالنسبة إلى التطبيقات التي تستخدم أيًا من Firebase Web API التي تحمل مساحة اسم، بدءًا من مكتبات compat
والإصدار 8 أو الإصدارات الأقدم، يجب أن تأخذ في الاعتبار
نقل البيانات إلى واجهة برمجة التطبيقات المُنشَأة من وحدات باستخدام التعليمات الواردة في هذا الدليل.
يفترض هذا الدليل أنّك على دراية بواجهة برمجة التطبيقات المستندة إلى مساحة الاسم وأنّك ستستفيد من أداة تجميع الوحدات مثل webpack أو Rollup للترقية و تطوير التطبيقات المُنشأة من وحدات بشكلٍ مستمر.
ننصح بشدة باستخدام أداة تجميع وحدات في بيئة التطوير. وفي حال عدم استخدام أحدهما، لن تتمكّن من الاستفادة من الفوائد الرئيسية لواجهة برمجة التطبيقات المُركّبة في تقليل حجم التطبيق. ستحتاج إلى استخدام npm أو yarn لتثبيت حزمة تطوير البرامج (SDK).
ستستند خطوات الترقية الواردة في هذا الدليل إلى تطبيق ويب خيالي يستخدم حِزم تطوير البرامج (SDK) Authentication وCloud Firestore. من خلال الاطّلاع على الأمثلة، يمكنك إتقان المفاهيم والخطوات العملية المطلوبة لترقية جميع حِزم تطوير البرامج (SDK) المتوافقة لـ Firebase Web.
لمحة عن المكتبات التي تتضمّن مساحة اسم (compat
)
يتوفّر نوعان من المكتبات لحزمة تطوير البرامج (SDK) على الإنترنت لمنصّة Firebase:
- الوحدات: واجهة جديدة لواجهة برمجة التطبيقات مصمّمة لتسهيل إزالة العناصر غير الضرورية (إزالة الرموز البرمجية غير المستخدَمة) لجعل تطبيق الويب صغيرًا وسريعًا قدر الإمكان.
- الحزمة المُنشِئة لمساحة الاسماء (
compat
): وهي واجهة برمجة تطبيقات مألوفة متوافقة تمامًا مع الإصدارات السابقة من حزمة SDK، ما يتيح لك الترقية بدون تغيير كل رمز Firebase دفعة واحدة. لا توفّر مكتبات التوافق مزايا تذكر أو مزايا قليلة في ما يتعلّق بالحجم أو الأداء مقارنةً بنظيراتها المستندة إلى مساحة الاسم.
يفترض هذا الدليل أنّك ستستفيد من مكتبات التوافق لتوفير عملية الترقية. تسمح لك هذه المكتبات بمواصلة استخدام الرمز المُحدَّد بمساحة اسم إلى جانب الرمز الذي تمت إعادة تنظيمه لواجهة برمجة التطبيقات المُجمَّعة. وهذا يعني أنّه يمكنك تجميع تطبيقك وتصحيح أخطاءه بسهولة أكبر أثناء عملية الترقية.
بالنسبة إلى التطبيقات التي تتعامل بشكل بسيط جدًا مع حزمة تطوير البرامج (SDK) لمنصة Firebase على الويب، مثل التطبيقات التي تُجري طلبًا بسيطًا فقط إلى واجهات برمجة التطبيقات Authentication، قد يكون من العملي إعادة صياغة الرموز القديمة التي تتضمّن مساحة اسم بدون استخدام مكتبات التوافق. إذا كنت بصدد ترقية تطبيق من هذا النوع، يمكنك اتّباع التعليمات الواردة في هذا الدليل لـ "واجهة برمجة التطبيقات المُركّبة" بدون استخدام مكتبات التوافق.
لمحة عن عملية الترقية
يتم تحديد نطاق كل خطوة من خطوات عملية الترقية حتى تتمكّن من إنهاء تعديل ملف ملف برمجي لتطبيقك ثم تجميعه وتشغيله بدون حدوث أي مشاكل. باختصار، في ما يلي الخطوات التي يجب اتّباعها لترقية تطبيق:
- أضِف المكتبات المُركّبة ومكتبات التوافق إلى تطبيقك.
- عدِّل عبارات الاستيراد في الرمز البرمجي إلى compat.
- أعِد صياغة رمز منتج واحد (مثل Authentication) ليصبح بالأسلوب المكوّن من وحدات.
- اختياري: في هذه المرحلة، عليك إزالة مكتبة التوافق Authentication ورمز التوافق لنظام التشغيل Authentication من أجل تحقيق ميزة حجم التطبيق المناسب لنظام التشغيل Authentication قبل المتابعة.
- أعِد صياغة الدوالّ لكل منتج (على سبيل المثال، Cloud Firestore وFCM وما إلى ذلك) إلى النمط المُجمَّع، ثمّ اجمعها واختبرها إلى أن تكتمل جميع المناطق.
- عدِّل رمز الإعداد إلى النمط المكوّن من وحدات.
- أزِل جميع عبارات التوافق والرموز البرمجية المتبقية للتوافق من تطبيقك.
الحصول على أحدث إصدار من حزمة تطوير البرامج (SDK)
للبدء، يمكنك الحصول على المكتبات المُركّبة ومكتبات التوافق باستخدام npm:
npm i firebase@11.3.0 # OR yarn add firebase@11.3.0
تعديل عمليات الاستيراد لتصبح متوافقة
للحفاظ على عمل الرمز البرمجي بعد تعديل التبعيات، غيِّر عبارات الاستيراد لاستخدام الإصدار "compat" من كل عملية استيراد. على سبيل المثال:
الإصدارات السابقة: الإصدار 8 أو الإصدارات الأقدم
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
After: compat
// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
إعادة صياغة التطبيق باستخدام النمط المكوّن من وحدات
في حين تستند واجهات برمجة التطبيقات المستندة إلى مساحة الاسم إلى نمط الخدمة ومساحة الاسم المقترنَين بنقاط، يعني النهج المُركّب أنّه سيتم تنظيم الرمز البرمجي بشكل أساسي حول الوظائف. في واجهة برمجة التطبيقات المُنشِئة من وحدات، لا تعرض حزمة firebase/app
وغيرها من الحِزم عملية تصدير شاملة تحتوي على جميع ال methods من الحزمة. بدلاً من ذلك، تُصدِّر الحِزم دوال فردية.
في واجهة برمجة التطبيقات المُجمَّعة، يتم تمرير الخدمات كوسيطة أولى، ثم تستخدم الدالة تفاصيل الخدمة لتنفيذ الباقي. لنطّلِع على كيفية عمل ذلك في مثالَين يعيدان هيكلة طلبات البيانات إلى واجهات برمجة التطبيقات Authentication وCloud Firestore.
المثال 1: إعادة صياغة دالة Authentication
قبل: compat
رمز التوافق مطابق للرمز الذي يتضمّن مساحة اسم، ولكن تم تغيير عمليات الاستيراد.
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
كما هو الحال في auth
في واجهة برمجة التطبيقات المستندة إلى مساحة الاسم، بل هي دالة
حرة تأخذ auth
كمَعلمتها الأولى.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
// Check for user status
});
تعديل طريقة التعامل مع طريقة المصادقة getRedirectResult
تُجري واجهة برمجة التطبيقات المُركّبة تغييرًا جذريًا في getRedirectResult
. عندما لا يتمّ استدعاء أيّ عملية إعادة توجيه، تعرض واجهة برمجة التطبيقات المُركّبة null
بدلاً من واجهة برمجة التطبيقات المستندة إلى مساحة الاسم، التي تعرض UserCredential
مع مستخدم null
.
قبل: compat
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
قبل: compat
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
في مثال سابق. يُرجى ملاحظة أنّه هناك اختلاف كبير بين تعليمات برمجة query
لإنشاء طلب بحث في واجهة برمجة التطبيقات المُجمَّعة، إذ لا تتضمّن تعليمات برمجة query
سلسلة، وأصبحت الآن طرقًا مثل 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
تُقدّم واجهة برمجة التطبيقات المُركّبة تغييرًا جذريًا تم فيه تغيير السمة
firestore.DocumentSnapshot.exists
إلى طريقة. إنّ
الوظيفة متطابقة بشكل أساسي (اختبار ما إذا كان المستند متوفّرًا)
ولكن عليك إعادة صياغة الرمز البرمجي لاستخدام الطريقة الأحدث كما هو موضّح:
Before:compat
if (snapshot.exists) {
console.log("the document exists");
}
بعد: وحدات
if (snapshot.exists()) {
console.log("the document exists");
}
المثال 3: دمج أنماط الرموز البرمجية المستندة إلى مساحة الاسم والوحدات
يتيح لك استخدام مكتبات التوافق أثناء الترقية مواصلة استخدام رمز مُحدَّد النطاق بجانب الرمز الذي تمت إعادة تنظيمه لواجهة برمجة التطبيقات المُركّبة. وهذا يعني أنّه يمكنك الاحتفاظ بالرمز البرمجي الحالي الذي يحمل مساحة اسم Cloud Firestore أثناء إعادة صياغة Authentication أو رمز حزمة تطوير البرامج (SDK) الأخرى لمنصّة Firebase ليصبح بالأسلوب المُركّب، مع مواصلة تجميع تطبيقك بنجاح باستخدام كلا الأسلوبَين لرمز البرمجي. وينطبق الأمر نفسه على رمز واجهة برمجة التطبيقات المُنشئ باستخدام مساحة اسم ورمز واجهة برمجة التطبيقات المُنشئ باستخدام وحدات داخل منتج مثل 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()
تهيئ الحالة
العمودية لكل من واجهات برمجة التطبيقات المتوافقة والمرنة، في حين أنّ دالة
initializeApp()
المرنة تهيئ الحالة للمرنة فقط.
قبل: compat
import firebase from "firebase/compat/app"
firebase.initializeApp({ /* config */ });
بعد: وحدات
import { initializeApp } from "firebase/app"
const firebaseApp = initializeApp({ /* config */ });
إزالة رمز التوافق
للاستفادة من مزايا حجم واجهة برمجة التطبيقات المُجمَّعة، عليك في النهاية
تحويل جميع عمليات الاستدعاء إلى النمط المجمَّع المعروض أعلاه وإزالة جميع عبارات
import "firebase/compat/*
من الرمز البرمجي. عند الانتهاء، يجب أن تصبح
المراجع إلى مساحة الاسم المطلق firebase.*
أو أي رمز
آخر في نمط واجهة برمجة التطبيقات المستندة إلى مساحة الاسم غير متوفّرة.
استخدام مكتبة compat من النافذة
تم تحسين واجهة برمجة التطبيقات المُنشِئة للمكوّنات للعمل مع المكوّنات بدلاً من عنصر
window
للمتصفّح. كانت الإصدارات السابقة من المكتبة تسمح بتحميل Firebase
وإدارته باستخدام مساحة الاسم window.firebase
. لا ننصح
باستخدام هذا الإجراء من الآن فصاعدًا لأنّه لا يسمح بإزالة الرموز غير المستخدَمة.
ومع ذلك، يعمل الإصدار المتوافق من حزمة تطوير البرامج (SDK) لـ JavaScript مع window
للمطوّرين الذين يفضّلون عدم بدء مسار الترقية المُركّبة على الفور.
<script src="https://www.gstatic.com/firebasejs/11.3.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.3.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.3.0/firebase-auth-compat.js"></script>
<script>
const firebaseApp = firebase.initializeApp({ /* Firebase config */ });
const db = firebaseApp.firestore();
const auth = firebaseApp.auth();
</script>
تستخدم مكتبة التوافق رموزًا نمطية في الخلفية، وتوفر واجهة برمجة التطبيقات نفسها التي توفّرها واجهة برمجة التطبيقات المستندة إلى مساحة الاسم. وهذا يعني أنّه يمكنك الرجوع إلى مرجع واجهة برمجة التطبيقات المستندة إلى مساحة الاسم ومقتطفات الرموز المستندة إلى مساحة الاسم للاطّلاع على التفاصيل. لا يُنصح باستخدام هذه الطريقة على المدى الطويل، ولكن كخطوة أولى للترقية إلى مكتبة مؤلفة من وحدات بالكامل.
مزايا حزمة SDK المكوّنة من وحدات والقيود المفروضة عليها
تتمتع حزمة SDK المُنشَأة من وحدات بالكامل بالمزايا التالية مقارنةً بالإصدارات السابقة:
- تتيح حِزم تطوير البرامج (SDK) المُركّبة تقليل حجم التطبيق بشكل كبير. وتتّبع هذه الطريقة تنسيق وحدات JavaScript الحديث، ما يتيح لك ممارسات "إزالة العناصر غير الضرورية" التي تستورد فيها العناصر التي يحتاجها تطبيقك فقط. استنادًا إلى تطبيقك، يمكن أن يؤدي استخدام ميزة "تقليل حجم حِزم البرامج" مع حزمة SDK المكوّنة من وحدات إلى تقليل حجم التطبيق بـ 80% مقارنةً بتطبيق مماثل تم إنشاؤه باستخدام واجهة برمجة التطبيقات المستندة إلى مساحة الاسم.
- ستستمر حزمة SDK المكوّنة من وحدات في الاستفادة من تطوير الميزات الجاري، في حين لن تستفيد واجهة برمجة التطبيقات المستندة إلى مساحة الاسم.