1. مقدمة
تاريخ آخر تعديل: 2022-11-16
إنشاء تطبيق Android باستخدام Firebase وJetpack Compose
في هذا الدرس التطبيقي حول الترميز، ستنشئ تطبيق Android باسم Make It So. تم إنشاء واجهة المستخدم لهذا التطبيق بالكامل باستخدام Jetpack Compose، وهي مجموعة أدوات حديثة من Android لإنشاء واجهة مستخدم أصلية، وهي سهلة الاستخدام وتتطلّب كتابة رمز برمجي أقل من كتابة ملفات .xml وربطها بالأنشطة أو الأجزاء أو طرق العرض.
تتمثّل الخطوة الأولى لفهم مدى توافق Firebase وJetpack Compose في فهم بنية Android الحديثة. تسهّل البنية الجيدة فهم النظام وتطويره وصيانته، لأنّها توضّح بشكل كبير كيفية تنظيم المكوّنات والتواصل مع بعضها البعض. في نظام التشغيل Android، تُعرف البنية المقترَحة باسم Model - View - ViewModel. يمثّل النموذج الطبقة التي تصل إلى البيانات في التطبيق. العرض هو طبقة واجهة المستخدم ويجب ألا يعرف أي شيء عن منطق النشاط التجاري. ويتم تطبيق منطق النشاط التجاري في ViewModel، ما يتطلّب أحيانًا أن يستدعي ViewModel طبقة Model.
ننصحك بشدة بقراءة هذه المقالة للتعرّف على كيفية تطبيق نمط Model - View - ViewModel على تطبيق Android تم إنشاؤه باستخدام Jetpack Compose، لأنّ ذلك سيجعل قاعدة الرموز البرمجية أسهل في الفهم ويسهّل إكمال الخطوات التالية.
ما ستنشئه
Make It So هو تطبيق بسيط لقوائم المهام يتيح للمستخدم إضافة المهام وتعديلها، وإضافة علامات وأولويات وتواريخ تسليم، ووضع علامة على المهام باعتبارها مكتملة. تعرض الصورتان أدناه الصفحتَين الرئيسيتَين لهذا التطبيق: صفحة إنشاء المهام والصفحة الرئيسية التي تتضمّن قائمة بالمهام التي تم إنشاؤها.
ستضيف بعض الميزات غير المتوفّرة في هذا التطبيق:
- مصادقة المستخدمين باستخدام عنوان البريد الإلكتروني وكلمة المرور
- إضافة أداة معالجة حدث إلى مجموعة Firestore وجعل واجهة المستخدِم تستجيب للتغييرات
- إضافة عمليات تتبُّع مخصّصة لمراقبة أداء رمز معيّن في التطبيق
- إنشاء مفتاح تشغيل/إيقاف ميزة باستخدام "الإعداد عن بُعد" واستخدام ميزة "الطرح على مراحل" لإطلاقها
ما ستتعلمه
- كيفية استخدام "مصادقة Firebase" و"مراقبة الأداء" و"الإعداد عن بُعد" وCloud Firestore في تطبيق Android حديث
- كيفية جعل واجهات برمجة تطبيقات Firebase تتوافق مع بنية MVVM
- كيفية عرض التغييرات التي تم إجراؤها باستخدام واجهات برمجة تطبيقات Firebase في واجهة مستخدم Compose
المتطلبات
- Android Studio Flamingo+
- محاكي Android مع المستوى 21 لواجهة برمجة التطبيقات أو مستوى أحدث
- الإلمام بلغة البرمجة Kotlin
2. الحصول على نموذج التطبيق وإعداد Firebase
الحصول على رمز التطبيق النموذجي
استنسِخ مستودع GitHub من سطر الأوامر:
git clone https://github.com/FirebaseExtended/make-it-so-android.git
إنشاء مشروع على Firebase
- سجِّل الدخول إلى وحدة تحكّم Firebase باستخدام حسابك على Google.
- انقر على الزر لإنشاء مشروع جديد، ثم أدخِل اسم المشروع (على سبيل المثال،
Compose Firebase codelab
). - انقر على متابعة.
- إذا طُلب منك ذلك، راجِع بنود Firebase واقبلها، ثم انقر على متابعة.
- (اختياري) فعِّل ميزة "المساعدة المستندة إلى الذكاء الاصطناعي" في وحدة تحكّم Firebase (المعروفة باسم "Gemini في Firebase").
- في هذا الدرس العملي، تحتاج إلى "إحصاءات Google" لاستخدام خيارات الاستهداف المتقدّمة مع "الإعداد عن بُعد"، لذا أبقِ زر التبديل مفعّلاً لخيار "إحصاءات Google". اتّبِع التعليمات الظاهرة على الشاشة لإعداد "إحصاءات Google".
- انقر على إنشاء مشروع، وانتظِر إلى أن يتم توفير مشروعك، ثم انقر على متابعة.
إضافة تطبيق Android إلى مشروعك على Firebase
في مشروع Firebase، يمكنك تسجيل تطبيقات مختلفة: لتطبيقات Android وiOS والويب وFlutter وUnity.
اختَر خيار Android، كما هو موضّح هنا:
بعد ذلك، اتّبِع الخطوات التالية:
- أدخِل
com.example.makeitso
كاسم للحزمة، ويمكنك إدخال لقب اختياريًا. في هذا الدرس العملي، لن تحتاج إلى إضافة شهادة توقيع تصحيح الأخطاء. - انقر على التالي لتسجيل تطبيقك والوصول إلى ملف إعداد Firebase.
- انقر على تنزيل ملف google-services.json لتنزيل ملف الإعداد وحفظه في الدليل
make-it-so-android/app
. - انقر على التالي. بما أنّ حِزم تطوير البرامج (SDK) لمنصة Firebase مضمّنة في ملف
build.gradle
في المشروع النموذجي، انقر على التالي للانتقال إلى الخطوات التالية. - انقر على المتابعة إلى وحدة التحكّم للانتهاء.
لكي يعمل تطبيق Make it So بشكل صحيح، عليك إجراء خطوتَين في Play Console قبل الانتقال إلى الرمز البرمجي: تفعيل موفّري المصادقة وإنشاء قاعدة بيانات Firestore.
إعداد المصادقة
أولاً، لنفعِّل خدمة "المصادقة" ليتمكّن المستخدمون من تسجيل الدخول إلى التطبيق:
- من قائمة إنشاء (Build)، اختَر المصادقة (Authentication)، ثم انقر على البدء (Get Started).
- من بطاقة طريقة تسجيل الدخول، اختَر البريد الإلكتروني/كلمة المرور وفعِّلها.
- بعد ذلك، انقر على إضافة موفّر جديد واختَر مجهول وفعِّله.
إعداد Cloud Firestore
بعد ذلك، يمكنك إعداد Firestore. ستستخدم Firestore لتخزين مهام المستخدم الذي سجّل الدخول. سيحصل كل مستخدم على مستند خاص به ضمن مجموعة في قاعدة البيانات.
- في اللوحة اليمنى من "وحدة تحكّم Firebase"، وسِّع إنشاء، ثم اختَر قاعدة بيانات Firestore.
- انقر على إنشاء قاعدة بيانات.
- اترك معرّف قاعدة البيانات مضبوطًا على
(default)
. - اختَر موقعًا لقاعدة البيانات، ثم انقر على التالي.
بالنسبة إلى تطبيق حقيقي، عليك اختيار موقع جغرافي قريب من المستخدمين. - انقر على البدء في وضع الاختبار. اقرأ بيان إخلاء المسؤولية عن قواعد الأمان.
في الخطوات التالية من هذا القسم، ستضيف "قواعد الأمان" لتأمين بياناتك. لا توزِّع تطبيقًا أو تعرضه بشكل علني بدون إضافة "قواعد الأمان" لقاعدة البيانات. - انقر على إنشاء.
لنخصّص بعض الوقت لإنشاء "قواعد أمان" قوية لقاعدة بيانات Firestore.
- افتح لوحة بيانات Firestore وانتقِل إلى علامة التبويب القواعد.
- عدِّل "قواعد الأمان" لتصبح على النحو التالي:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /tasks/{document} {
allow create: if request.auth != null;
allow read, update, delete: if request.auth != null
&& resource.data.userId == request.auth.uid
&& request.data.userId == resource.data.userId;
}
}
}
تنصّ هذه القواعد بشكل أساسي على أنّه يمكن لأي مستخدم مسجّل الدخول إلى التطبيق إنشاء مستند لنفسه ضمن أي مجموعة. بعد إنشاء المستند، لن يتمكّن أحد سوى المستخدم الذي أنشأه من الاطّلاع عليه أو تعديله أو حذفه.
تشغيل التطبيق
أنت الآن جاهز لتشغيل التطبيق. افتح المجلد make-it-so-android/start
في Android Studio وشغِّل التطبيق (يمكن إجراء ذلك باستخدام "محاكي Android" أو جهاز Android حقيقي).
3- مصادقة Firebase
ما هي الميزة التي ستتم إضافتها؟
في الحالة الحالية للتطبيق التجريبي Make It So، يمكن للمستخدم بدء استخدام التطبيق بدون الحاجة إلى تسجيل الدخول أولاً. ويستخدم المصادقة المجهولة لتحقيق ذلك. ومع ذلك، لا تسمح الحسابات المجهولة للمستخدم بالوصول إلى بياناته على أجهزة أخرى أو حتى في الجلسات المستقبلية. على الرغم من أنّ المصادقة المجهولة الهوية مفيدة في عملية الإعداد السلس، يجب أن توفّر دائمًا للمستخدمين خيار التبديل إلى شكل آخر من أشكال تسجيل الدخول. مع أخذ ذلك في الاعتبار، ستضيف في هذا الدرس التطبيقي حول الترميز ميزة المصادقة باستخدام البريد الإلكتروني وكلمة المرور إلى تطبيق Make It So.
حان وقت البرمجة!
فور إنشاء المستخدم حسابًا عن طريق كتابة عنوان بريد إلكتروني وكلمة مرور، عليك أن تطلب من واجهة برمجة التطبيقات Firebase Authentication الحصول على بيانات اعتماد البريد الإلكتروني، ثم ربط بيانات الاعتماد الجديدة بالحساب المجهول. افتح الملف AccountServiceImpl.kt
في "استوديو Android" وعدِّل الدالة linkAccount
ليصبح شكلها كما يلي:
model/service/impl/AccountServiceImpl.kt
override suspend fun linkAccount(email: String, password: String) {
val credential = EmailAuthProvider.getCredential(email, password)
auth.currentUser!!.linkWithCredential(credential).await()
}
الآن، افتح SignUpViewModel.kt
واستدعِ دالة الخدمة linkAccount
داخل كتلة launchCatching
من الدالة onSignUpClick
:
screens/sign_up/SignUpViewModel.kt
launchCatching {
accountService.linkAccount(email, password)
openAndPopUp(SETTINGS_SCREEN, SIGN_UP_SCREEN)
}
يحاول أولاً إجراء المصادقة، وإذا نجحت العملية، ينتقل إلى الشاشة التالية (SettingsScreen
). وبما أنّك تنفّذ هذه العمليات داخل كتلة launchCatching
، إذا حدث خطأ في السطر الأول، سيتم رصد الاستثناء ومعالجته، ولن يتم الوصول إلى السطر الثاني على الإطلاق.
بعد إعادة فتح SettingsScreen
، عليك التأكّد من عدم ظهور خيارَي تسجيل الدخول وإنشاء حساب، لأنّ المستخدم قد أثبت هويته الآن. لإجراء ذلك، لنستمع إلى حالة المستخدم الحالي (المتوفرة في AccountService.kt
) لمعرفة ما إذا كان الحساب مجهولاً أم لا.SettingsViewModel
لإجراء ذلك، عدِّل uiState
في SettingsViewModel.kt
ليصبح على النحو التالي:
screens/settings/SettingsViewModel.kt
val uiState = accountService.currentUser.map {
SettingsUiState(it.isAnonymous)
}
آخر خطوة عليك اتّخاذها هي تعديل uiState
في SettingsScreen.kt
لجمع الحالات التي تصدرها SettingsViewModel
:
screens/settings/SettingsScreen.kt
val uiState by viewModel.uiState.collectAsState(
initial = SettingsUiState(false)
)
الآن، في كل مرة يتغير فيها المستخدم، ستتم إعادة إنشاء SettingsScreen
لعرض الخيارات وفقًا لحالة المصادقة الجديدة للمستخدم.
حان وقت الاختبار!
شغِّل Make it So وانتقِل إلى الإعدادات من خلال النقر على رمز الترس في أعلى يسار الشاشة. بعد ذلك، انقر على خيار إنشاء حساب:
اكتب عنوان بريد إلكتروني صالحًا وكلمة مرور قوية لإنشاء حسابك. من المفترض أن ينجح ذلك وأن تتم إعادة توجيهك إلى صفحة الإعدادات، حيث سيظهر لك خياران جديدان: تسجيل الخروج وحذف حسابك. يمكنك الاطّلاع على الحساب الجديد الذي تم إنشاؤه في لوحة بيانات "المصادقة" على وحدة تحكّم Firebase من خلال النقر على علامة التبويب "المستخدمون".
4. Cloud Firestore
ما هي الميزة التي ستتم إضافتها؟
بالنسبة إلى Cloud Firestore، ستضيف أداة معالجة إلى مجموعة Firestore التي تخزّن المستندات التي تمثّل المهام المعروضة في Make it So. بعد إضافة أداة المعالجة هذه، ستتلقّى كل تعديل يتم إجراؤه على هذه المجموعة.
حان وقت البرمجة!
عدِّل Flow
available in StorageServiceImpl.kt
ليصبح على النحو التالي:
model/service/impl/StorageServiceImpl.kt
override val tasks: Flow<List<Task>>
get() =
auth.currentUser.flatMapLatest { user ->
firestore.collection(TASK_COLLECTION).whereEqualTo(USER_ID_FIELD, user.id).dataObjects()
}
تضيف هذه التعليمة البرمجية أداة معالجة إلى مجموعة المهام استنادًا إلى user.id
. يتم تمثيل كل مهمة بمستند في مجموعة باسم tasks
، ويحتوي كل مستند على حقل باسم userId
. يُرجى العِلم أنّه سيتم إصدار Flow
جديد إذا تغيّرت حالة currentUser
(من خلال تسجيل الخروج مثلاً).
عليك الآن التأكّد من أنّ Flow
في TasksViewModel.kt
يعرض القيمة نفسها المعروضة في الخدمة:
screens/tasks/TasksViewModel.kt
val tasks = storageService.tasks
آخر خطوة هي جعل composable function
في TasksScreens.kt
، الذي يمثّل واجهة المستخدم، على دراية بهذا التسلسل وجمعه كحالة. في كل مرة تتغير فيها الحالة، ستعيد الدالة القابلة للإنشاء تركيب نفسها تلقائيًا وتعرض للمستخدم أحدث حالة. أضِف ما يلي إلى TasksScreen composable function
:
screens/tasks/TasksScreen.kt
val tasks = viewModel
.tasks
.collectAsStateWithLifecycle(emptyList())
بعد أن تتمكّن الدالة البرمجية القابلة للإنشاء من الوصول إلى هذه الحالات، يمكنك تعديل LazyColumn
(وهي البنية التي تستخدمها لعرض قائمة على الشاشة) لتصبح على النحو التالي:
screens/tasks/TasksScreen.kt
LazyColumn {
items(tasks.value, key = { it.id }) { taskItem ->
TaskItem( [...] )
}
}
حان وقت الاختبار!
لاختبار ما إذا كان قد تم تفعيلها، أضِف مهمة جديدة باستخدام التطبيق (من خلال النقر على زر الإضافة في أسفل يسار الشاشة). بعد الانتهاء من إنشاء المهمة، من المفترض أن تظهر في مجموعة Firestore في Firestore Console. إذا سجّلت الدخول إلى Make it So على أجهزة أخرى باستخدام الحساب نفسه، ستتمكّن من تعديل مهامك ومشاهدة تعديلها على جميع الأجهزة في الوقت الفعلي.
5- مراقبة الأداء
ما هي الميزة التي ستتم إضافتها؟
يُعدّ الأداء من الجوانب المهمة جدًا التي يجب الانتباه إليها، لأنّه من المرجّح أن يتوقف المستخدمون عن استخدام تطبيقك إذا لم يكن الأداء جيدًا واستغرقوا وقتًا طويلاً لإكمال مهمة بسيطة باستخدام التطبيق. لهذا السبب، من المفيد أحيانًا جمع بعض المقاييس حول رحلة معيّنة يجريها المستخدم في تطبيقك، وللمساعدة في ذلك، يوفّر لك منتج "مراقبة الأداء في Firebase" عمليات تتبُّع مخصّصة. اتّبِع الخطوات التالية لإضافة عمليات تتبُّع مخصّصة وقياس الأداء في أجزاء مختلفة من الرمز في Make it So.
حان وقت البرمجة!
إذا فتحت الملف Performance.kt
، سيظهر لك دالة مضمّنة باسم trace. تستدعي هذه الدالة واجهة برمجة التطبيقات Performance Monitoring لإنشاء عملية تتبُّع مخصّصة، مع تمرير اسم عملية التتبُّع كمعلَمة. المَعلمة الأخرى التي تظهر لك هي مجموعة الرموز التي تريد مراقبتها. المقياس التلقائي الذي يتمّ جمعه لكلّ عملية تتبُّع هو الوقت المستغرَق لتنفيذها بالكامل:
model/service/Performance.kt
inline fun <T> trace(name: String, block: Trace.() -> T): T = Trace.create(name).trace(block)
يمكنك اختيار أجزاء من قاعدة الرموز البرمجية تعتقد أنّها مهمة للقياس وإضافة عمليات تتبُّع مخصّصة إليها. في ما يلي مثال على إضافة عملية تتبُّع مخصّصة إلى الدالة linkAccount
التي رأيتها سابقًا (في AccountServiceImpl.kt
) في هذا الدرس العملي:
model/service/impl/AccountServiceImpl.kt
override suspend fun linkAccount(email: String, password: String): Unit =
trace(LINK_ACCOUNT_TRACE) {
val credential = EmailAuthProvider.getCredential(email, password)
auth.currentUser!!.linkWithCredential(credential).await()
}
حان دورك الآن! أضِف بعض عمليات التتبُّع المخصّصة إلى تطبيق Make it So وانتقِل إلى القسم التالي لاختبار ما إذا كانت تعمل على النحو المتوقّع.
حان وقت الاختبار!
بعد الانتهاء من إضافة عمليات التتبُّع المخصّصة، شغِّل التطبيق وتأكَّد من استخدام الميزات التي تريد قياسها عدة مرات. بعد ذلك، انتقِل إلى وحدة تحكّم Firebase ولوحة بيانات الأداء. في أسفل الشاشة، ستجد ثلاث علامات تبويب: طلبات الشبكة وعمليات التتبُّع المخصّصة وعرض الشاشة.
انتقِل إلى علامة التبويب عمليات التتبُّع المخصّصة وتأكَّد من عرض عمليات التتبُّع التي أضفتها في قاعدة الرموز، ومن إمكانية الاطّلاع على المدة التي يستغرقها عادةً تنفيذ أجزاء الرموز هذه.
6. الإعداد عن بُعد
ما هي الميزة التي ستتم إضافتها؟
تتوفّر العديد من حالات الاستخدام لميزة "الإعداد عن بُعد"، بدءًا من تغيير مظهر تطبيقك عن بُعد إلى ضبط سلوكيات مختلفة لشرائح المستخدمين المختلفة. في هذا الدرس العملي، ستستخدم ميزة "الإعداد عن بُعد" لإنشاء مفتاح تفعيل ميزة يعرض ميزة تعديل المهمة الجديدة أو يخفيها في تطبيق Make it So.
حان وقت البرمجة!
أول ما عليك فعله هو إنشاء الإعداد في وحدة تحكّم Firebase. لإجراء ذلك، عليك الانتقال إلى لوحة بيانات "الإعداد عن بُعد" والنقر على الزر إضافة مَعلمة. املأ الحقول وفقًا للصورة أدناه:
بعد ملء جميع الحقول، يمكنك النقر على الزر حفظ ثم على نشر. بعد إنشاء المَعلمة وإتاحتها لقاعدة الرموز، عليك إضافة الرمز الذي سيجلب القيم الجديدة إلى تطبيقك. افتح ملف ConfigurationServiceImpl.kt
وعدِّل تنفيذ هاتين الدالتين:
model/service/impl/ConfigurationServiceImpl.kt
override suspend fun fetchConfiguration(): Boolean {
return remoteConfig.fetchAndActivate().await()
}
override val isShowTaskEditButtonConfig: Boolean
get() = remoteConfig[SHOW_TASK_EDIT_BUTTON_KEY].asBoolean()
تسترد الدالة الأولى القيم من الخادم، ويتم استدعاؤها فور بدء تشغيل التطبيق، وذلك في SplashViewModel.kt
. وهي أفضل طريقة لضمان توفّر أحدث القيم في جميع الشاشات منذ البداية. لن تكون تجربة المستخدم جيدة إذا غيّرت واجهة المستخدم أو سلوك التطبيق لاحقًا عندما يكون المستخدم بصدد تنفيذ إجراء ما.
تعرض الدالة الثانية القيمة المنطقية التي تم نشرها للمعلمة التي أنشأتها للتو في Play Console. عليك استرداد هذه المعلومات في TasksViewModel.kt
، وذلك عن طريق إضافة ما يلي إلى الدالة loadTaskOptions
:
screens/tasks/TasksViewModel.kt
fun loadTaskOptions() {
val hasEditOption = configurationService.isShowTaskEditButtonConfig
options.value = TaskActionOption.getOptions(hasEditOption)
}
أنت تسترجع القيمة في السطر الأول، وتستخدمها لتحميل خيارات القائمة لعناصر المهام في السطر الثاني. إذا كانت القيمة false
، يعني ذلك أنّ القائمة لن تتضمّن خيار التعديل. بعد الحصول على قائمة الخيارات، عليك التأكّد من أنّ واجهة المستخدم تعرضها بشكل صحيح. أثناء إنشاء تطبيق باستخدام Jetpack Compose، عليك البحث عن composable function
الذي يحدّد شكل واجهة المستخدم الخاصة بـ TasksScreen
. لذا، افتح الملف TasksScreen.kt
وعدِّل LazyColum
للإشارة إلى الخيارات المتاحة في TasksViewModel.kt
:
screens/tasks/TasksScreen.kt
val options by viewModel.options
LazyColumn {
items(tasks.value, key = { it.id }) { taskItem ->
TaskItem(
options = options,
[...]
)
}
}
TaskItem
هو composable function
آخر يحدّد شكل واجهة المستخدم لمهمة واحدة. وتتضمّن كل مهمة قائمة خيارات تظهر عندما ينقر المستخدم على رمز النقاط الثلاث في نهايتها.
حان وقت الاختبار!
أنت الآن جاهز لتشغيل التطبيق. تأكَّد من أنّ القيمة التي نشرتها باستخدام وحدة تحكّم Firebase تتطابق مع سلوك التطبيق:
- إذا كان
false
، من المفترض أن يظهر لك خياران فقط عند النقر على رمز النقاط الثلاث. - إذا كان
true
، من المفترض أن تظهر لك ثلاثة خيارات عند النقر على رمز النقاط الثلاث.
جرِّب تغيير القيمة بضع مرات في Console وأعِد تشغيل التطبيق. بهذه البساطة يمكنك إطلاق ميزات جديدة في تطبيقك باستخدام "الإعداد عن بُعد".
7. تهانينا
تهانينا، لقد نجحت في إنشاء تطبيق Android باستخدام Firebase وJetpack Compose.
لقد أضفت "مصادقة Firebase" و"مراقبة الأداء" و"الإعداد عن بُعد" وCloud Firestore إلى تطبيق Android تم إنشاؤه بالكامل باستخدام Jetpack Compose لواجهة المستخدم، كما جعلته يتوافق مع بنية MVVM المقترَحة.
مزيد من المعلومات
- إنشاء تطبيق Android باستخدام Firebase وCompose
- إضافة "مصادقة Firebase" إلى تطبيق Jetpack Compose
- إضافة Cloud Firestore إلى تطبيق Jetpack Compose
- إضافة Coroutines وFlow إلى تطبيق Android تم إنشاؤه باستخدام Firebase وCompose
- إضافة خدمة "مراقبة أداء Firebase" إلى تطبيق Jetpack Compose
- إضافة ميزة "الإعداد عن بُعد في Firebase" إلى تطبيق Jetpack Compose