الترقية من واجهة برمجة التطبيقات المستندة إلى مساحة الاسم إلى التطبيق المكوّن من وحدات

على التطبيقات التي تستخدم أي واجهة برمجة تطبيقات للويب من Firebase ضمن مساحة الاسم، بدءًا من مكتبات compat وصولاً إلى الإصدار 8 أو الإصدارات الأقدم، أن تنقل بياناتها إلى واجهة برمجة التطبيقات النمطية باستخدام التعليمات الواردة في هذا الدليل.

يفترض هذا الدليل أنّك على دراية بواجهة برمجة التطبيقات namespaced API وأنّك ستستفيد من أداة تجميع الوحدات، مثل webpack أو Rollup، لترقية التطبيق وتطويره بشكل نمطي مستمر.

ننصحك بشدة باستخدام أداة تجميع الوحدات في بيئة التطوير. إذا لم تستخدم إحدى هذه الأدوات، لن تتمكّن من الاستفادة من المزايا الرئيسية لواجهة برمجة التطبيقات النمطية في تقليل حجم التطبيق. ستحتاج إلى npm أو yarn لتثبيت حزمة تطوير البرامج (SDK).

ستستند خطوات الترقية في هذا الدليل إلى تطبيق ويب وهمي يستخدم حزمتَي تطوير البرامج (SDK) لـ Authentication وCloud Firestore. من خلال الاطّلاع على الأمثلة، يمكنك إتقان المفاهيم والخطوات العملية اللازمة لترقية جميع حِزم تطوير البرامج (SDK) المتوافقة مع الويب من Firebase.

لمحة عن مكتبات مساحة الاسم (compat)

يتوفّر نوعان من المكتبات لحزمة تطوير البرامج (SDK) للويب من Firebase:

  • النمطية : هي واجهة برمجة تطبيقات جديدة مصمّمة لتسهيل عملية إزالة الرموز غير المستخدَمة من شجرة الوحدات (إزالة الرموز غير المستخدَمة) لـ جعل تطبيق الويب صغيرًا وسريعًا قدر الإمكان.
  • ضمن مساحة الاسم (compat) : هي واجهة برمجة تطبيقات مألوفة ومتوافقة تمامًا مع الإصدارات السابقة من حزمة تطوير البرامج (SDK)، ما يتيح لك الترقية بدون تغيير كل رموز Firebase البرمجية في آنٍ واحد. لا تقدّم مكتبات التوافق مزايا كبيرة أو أي مزايا على الإطلاق من حيث الحجم أو الأداء مقارنةً بنظيراتها ضمن مساحة الاسم.

يفترض هذا الدليل أنّك ستستفيد من مكتبات التوافق لتسهيل عملية الترقية. تتيح لك هذه المكتبات مواصلة استخدام الرموز البرمجية ضمن مساحة الاسم إلى جانب الرموز البرمجية التي تمّت إعادة هيكلتها لواجهة برمجة التطبيقات النمطية. يعني ذلك أنّه يمكنك تجميع تطبيقك وتصحيح الأخطاء فيه بسهولة أكبر أثناء العمل على عملية الترقية.

بالنسبة إلى التطبيقات التي تستخدم حزمة تطوير البرامج (SDK) للويب من Firebase بشكل محدود جدًا، مثل تطبيق لا يُجري سوى طلب بسيط لواجهات برمجة التطبيقات Authentication، قد يكون من العملي إعادة هيكلة الرموز البرمجية القديمة ضمن مساحة الاسم بدون استخدام مكتبات التوافق. إذا كنت بصدد ترقية أحد هذه التطبيقات، يمكنك اتّباع التعليمات الواردة في هذا الدليل بشأن "واجهة برمجة التطبيقات النمطية" بدون استخدام مكتبات التوافق.

لمحة عن عملية الترقية

تم تحديد نطاق كل خطوة من خطوات عملية الترقية بحيث يمكنك الانتهاء من تعديل مصدر تطبيقك ثم تجميعه وتشغيله بدون حدوث أي أعطال. في ما يلي ملخّص للإجراءات التي ستتّخذها لترقية تطبيق:

  1. أضِف المكتبات النمطية ومكتبات التوافق إلى تطبيقك.
  2. عدِّل عبارات الاستيراد في الرموز البرمجية لتصبح متوافقة.
  3. أعِد هيكلة الرموز البرمجية لمنتج واحد (مثل Authentication) لتصبح نمطية.
  4. اختياري: في هذه المرحلة، يمكنك إزالة مكتبة التوافق لـ Authentication والرموز البرمجية المتوافقة لـ Authentication للاستفادة من ميزة تقليل حجم التطبيق لـ Authentication قبل المتابعة.
  5. أعِد هيكلة الدوال لكل منتج (مثل Cloud Firestore, FCM, وما إلى ذلك) لتصبح نمطية، وجمِّعها واختبِرها إلى أن تكتمل جميع الأقسام.
  6. عدِّل رمز الإعداد ليصبح نمطيًا.
  7. أزِل جميع عبارات التوافق والرموز البرمجية المتوافقة المتبقية من تطبيقك.

الحصول على أحدث إصدار من حزمة تطوير البرامج (SDK)

للبدء، احصل على المكتبات النمطية ومكتبات التوافق باستخدام npm:

npm i firebase@12.15.0

# OR

yarn add firebase@12.15.0

تعديل عمليات الاستيراد لتصبح متوافقة

للحفاظ على عمل الرموز البرمجية بعد تعديل التبعيات، غيِّر عبارات الاستيراد لاستخدام الإصدار "المتوافق" من كل عملية استيراد. على سبيل المثال:

قبل: الإصدار 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';

إعادة الهيكلة لتصبح نمطية

في حين أنّ واجهات برمجة التطبيقات ضمن مساحة الاسم تستند إلى مساحة اسم ونمط خدمة متسلسلين بنقاط، يعني النهج النمطي أنّ الرموز البرمجية ستكون منظّمة بشكل أساسي حول الدوال. في modular API، لا تعرض حزمة firebase/app والحِزم الأخرى عملية تصدير شاملة تحتوي على جميع الطرق من الحزمة. بدلاً من ذلك، تصدِّر الحِزم دوال فردية.

في واجهة برمجة التطبيقات النمطية، يتم تمرير الخدمات كمعلَمة أولى، ثم تستخدم الدالة تفاصيل الخدمة لإجراء باقي العمليات. لنلقِ نظرة على كيفية عمل ذلك في مثالَين يعيدان هيكلة طلبات إلى واجهات برمجة التطبيقات لميزة Authentication وCloud Firestore.

المثال 1: إعادة هيكلة دالة Authentication

قبل: متوافق

تتطابق الرموز البرمجية المتوافقة مع الرموز البرمجية ضمن مساحة الاسم، ولكن تم تغيير عمليات الاستيراد.

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 كما هو الحال في namespaced API؛ بل هي دالة حرة تأخذ auth كمعلَمة أولى.

import { getAuth, onAuthStateChanged } from "firebase/auth";

const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
  // Check for user status
});

تعديل طريقة التعامل مع طريقة المصادقة getRedirectResult

تُدخل واجهة برمجة التطبيقات النمطية تغييرًا غير متوافق في getRedirectResult. عند عدم استدعاء أي عملية إعادة توجيه، تعرض واجهة برمجة التطبيقات النمطية null بدلاً من واجهة برمجة التطبيقات ضمن مساحة الاسم التي كانت تعرض 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 في مثال سابق. يُرجى العِلم أنّ الرموز البرمجية لإنشاء طلب بحث مختلفة جدًا في واجهة برمجة التطبيقات النمطية، إذ لا يوجد تسلسل، ويتم الآن عرض طرق مثل 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());
});

تعديل المراجع إلى DocumentSnapshot.exists في Firestore

تُدخل واجهة برمجة التطبيقات النمطية تغييرًا غير متوافق تم بموجبه تغيير السمة firestore.DocumentSnapshot.exists إلى طريقة. تظل الوظيفة هي نفسها بشكل أساسي (اختبار ما إذا كان المستند موجودًا)، ولكن عليك إعادة هيكلة الرموز البرمجية لاستخدام الطريقة الأحدث كما هو موضّح أدناه:

قبل:متوافق

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() إلا حالة واجهة برمجة التطبيقات النمطية.

قبل: متوافق

import firebase from "firebase/compat/app"

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

بعد: نمطي

import { initializeApp } from "firebase/app"

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

إزالة الرموز البرمجية المتوافقة

للاستفادة من مزايا تقليل الحجم التي توفّرها واجهة برمجة التطبيقات النمطية، عليك في النهاية تحويل جميع عمليات الاستدعاء إلى النمط النمطي الموضّح أعلاه وإزالة جميع عبارات import "firebase/compat/* من الرموز البرمجية. عند الانتهاء، لن يكون هناك أي مراجع لمساحة الاسم العامة firebase.* أو أي رموز برمجية أخرى بنمط namespaced API.

استخدام مكتبة التوافق من النافذة

تم تحسين واجهة برمجة التطبيقات النمطية للعمل مع الوحدات بدلاً من عنصر window في المتصفّح. كانت الإصدارات السابقة من المكتبة تسمح بتحميل Firebase وإدارته باستخدام مساحة الاسم window.firebase. لا ننصح بذلك من الآن فصاعدًا لأنّه لا يسمح بإزالة الرموز البرمجية غير المستخدَمة. ومع ذلك، يعمل الإصدار المتوافق من حزمة تطوير البرامج (SDK) JavaScript مع window للمطوّرين الذين يفضّلون عدم البدء فورًا بمسار الترقية النمطية.

<script src="https://www.gstatic.com/firebasejs/12.15.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/12.15.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/12.15.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 Module الحديث، ما يسمح بممارسات "إزالة الرموز غير المستخدَمة من شجرة الوحدات" التي تستورد فيها العناصر التي يحتاجها تطبيقك فقط. اعتمادًا على تطبيقك، يمكن أن تؤدي عملية إزالة الرموز غير المستخدَمة من شجرة الوحدات باستخدام حزمة تطوير البرامج (SDK) النمطية إلى تقليل عدد الكيلوبايت بنسبة% 80 مقارنةً بتطبيق مماثل تم إنشاؤه باستخدام واجهة برمجة التطبيقات ضمن مساحة الاسم.
  • ستستمر حزمة تطوير البرامج (SDK) النمطية في الاستفادة من تطوير الميزات المستمر، بينما لن تستفيد واجهة برمجة التطبيقات ضمن مساحة الاسم من ذلك.