1. نظرة عامة

صورة: تطبيق محادثات Friendly Chat يعمل.
مرحبًا بك في درس Friendly Chat التطبيقي حول الترميز. في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية استخدام منصة Firebase لإنشاء تطبيق محادثات على Android.
أهداف الدورة التعليمية
- كيفية استخدام خدمة "مصادقة Firebase" للسماح للمستخدمين بتسجيل الدخول
- كيفية مزامنة البيانات باستخدام "قاعدة بيانات Firebase في الوقت الفعلي"
- كيفية تخزين الملفات الثنائية في "مساحة تخزين سحابية لـ Firebase"
- كيفية استخدام "مجموعة أدوات المحاكاة المحلية لـ Firebase" لتطوير تطبيق Android باستخدام Firebase
المتطلبات
- أحدث إصدار من استوديو Android
- Android Emulator يعمل بالإصدار 5.0 من نظام التشغيل Android أو إصدار أحدث
- الإصدار 10 من Node.js أو إصدار أحدث (لاستخدام مجموعة أدوات المحاكاة)
- الإصدار 8 من Java أو إصدار أحدث لتثبيت Java، اتّبِع هذه التعليمات، وللتحقّق من إصدارك، شغِّل الأمر
java -version. - الإلمام بلغة البرمجة Kotlin
2. الحصول على الرمز النموذجي
إنشاء نسخة طبق الأصل من المستودع
استنسِخ مستودع GitHub من سطر الأوامر:
$ git clone https://github.com/firebase/codelab-friendlychat-android
الاستيراد إلى "استوديو Android"
في "استوديو Android"، انقر على ملف (File) > فتح (Open)، ثم اختَر دليل build-android-start (
) من الدليل الذي نزّلت منه نموذج الرمز البرمجي.
من المفترض أن يكون مشروع build-android-start مفتوحًا الآن في "استوديو Android". إذا ظهر لك تحذير بشأن عدم توفّر ملف google-services.json، لا داعي للقلق. سيتم إضافته في خطوة لاحقة.
التحقّق من التبعيات
في هذا الدرس العملي، تمت إضافة جميع التبعيات التي ستحتاج إليها، ولكن من المهم معرفة كيفية إضافة حزمة تطوير البرامج (SDK) لبرنامج Firebase إلى تطبيقك:
build.gradle.kts
plugins {
id("com.android.application") version "8.0.0" apply false
id("com.android.library") version "8.0.0" apply false
id("org.jetbrains.kotlin.android") version "1.8.20" apply false
// The google-services plugin is required to parse the google-services.json file
id("com.google.gms.google-services") version "4.3.15" apply false
}
app/build.gradle.kts
plugins {
id("com.android.application")
id("kotlin-android")
id("com.google.gms.google-services")
}
android {
// ...
}
dependencies {
// ...
// Google Sign In SDK
implementation("com.google.android.gms:play-services-auth:20.5.0")
// Firebase SDK
implementation(platform("com.google.firebase:firebase-bom:32.0.0"))
implementation("com.google.firebase:firebase-database-ktx")
implementation("com.google.firebase:firebase-storage-ktx")
implementation("com.google.firebase:firebase-auth-ktx")
// Firebase UI Library
implementation("com.firebaseui:firebase-ui-auth:8.0.2")
implementation("com.firebaseui:firebase-ui-database:8.0.2")
}
3- تثبيت Firebase CLI
في هذا الدرس العملي، ستستخدم مجموعة أدوات المحاكاة المحلية لـ Firebase لمحاكاة Firebase Auth وقاعدة بيانات الوقت الفعلي وCloud Storage محليًا. يوفّر ذلك بيئة تطوير محلية آمنة وسريعة وبدون تكلفة لإنشاء تطبيقك.
تثبيت Firebase CLI
عليك أولاً تثبيت Firebase CLI. إذا كنت تستخدم نظام التشغيل macOS أو Linux، يمكنك تنفيذ أمر cURL التالي:
curl -sL https://firebase.tools | bash
إذا كنت تستخدم نظام التشغيل Windows، يُرجى قراءة تعليمات التثبيت للحصول على ملف ثنائي مستقل أو للتثبيت من خلال npm.
بعد تثبيت واجهة سطر الأوامر، يجب أن يؤدي تنفيذ الأمر firebase --version إلى عرض الإصدار 9.0.0 أو إصدار أحدث:
$ firebase --version 9.0.0
تسجيل الدخول
نفِّذ الأمر firebase login لربط واجهة سطر الأوامر بحسابك على Google. سيؤدي ذلك إلى فتح نافذة متصفّح جديدة لإكمال عملية تسجيل الدخول. احرص على اختيار الحساب نفسه الذي استخدمته عند إنشاء مشروع Firebase الخاص بك في وقت سابق.
4. الربط بمجموعة أدوات المحاكاة المحلية لـ Firebase
بدء تشغيل المحاكيات
في الوحدة الطرفية، نفِّذ الأمر التالي من جذر دليل codelab-friendlychat-android المحلي:
firebase emulators:start --project=demo-friendlychat-android
من المفترض أن تظهر لك بعض السجلات على النحو التالي. تم تحديد قيم المنفذ في ملف firebase.json الذي تم تضمينه في نموذج الرمز البرمجي المستنسخ.
$ firebase emulators:start --project=demo-friendlychat-android
i emulators: Starting emulators: auth, database, storage
i emulators: Detected demo project ID "demo-friendlychat-android", emulated services will use a demo configuration and attempts to access non-emulated services for this project will fail.
i database: Database Emulator logging to database-debug.log
i ui: Emulator UI logging to ui-debug.log
┌─────────────────────────────────────────────────────────────┐
│ ✔ All emulators ready! It is now safe to connect your app. │
│ i View Emulator UI at http://localhost:4000 │
└─────────────────────────────────────────────────────────────┘
┌────────────────┬────────────────┬────────────────────────────────┐
│ Emulator │ Host:Port │ View in Emulator UI │
├────────────────┼────────────────┼────────────────────────────────┤
│ Authentication │ localhost:9099 │ http://localhost:4000/auth │
├────────────────┼────────────────┼────────────────────────────────┤
│ Database │ localhost:9000 │ http://localhost:4000/database │
├────────────────┼────────────────┼────────────────────────────────┤
│ Storage │ localhost:9199 │ http://localhost:4000/storage │
└────────────────┴────────────────┴────────────────────────────────┘
Emulator Hub running at localhost:4400
Other reserved ports: 4500
Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.
انتقِل إلى http://localhost:4000 في متصفّح الويب لعرض واجهة مستخدم "مجموعة أدوات المحاكاة" من Firebase:

اترك الأمر emulators:start قيد التشغيل لبقية الدرس العملي.
ربط تطبيقك
في "استوديو Android"، افتح MainActivity.kt، ثم أضِف الرمز التالي داخل طريقة onCreate:
// When running in debug mode, connect to the Firebase Emulator Suite.
// "10.0.2.2" is a special IP address which allows the Android Emulator
// to connect to "localhost" on the host computer. The port values (9xxx)
// must match the values defined in the firebase.json file.
if (BuildConfig.DEBUG) {
Firebase.database.useEmulator("10.0.2.2", 9000)
Firebase.auth.useEmulator("10.0.2.2", 9099)
Firebase.storage.useEmulator("10.0.2.2", 9199)
}
5- تشغيل التطبيق النموذجي
إضافة ملف google-services.json
لكي يتمكّن تطبيق Android من الاتصال بمنصة Firebase، يجب إضافة ملف google-services.json داخل المجلد app في مشروع Android. لأغراض هذا الدرس التطبيقي حول الترميز، قدّمنا ملف JSON وهميًا يتيح لك الاتصال بـ مجموعة أدوات محاكاة Firebase.
انسخ الملف mock-google-services.json إلى المجلد build-android-start/app باسم google-services.json:
cp mock-google-services.json build-android-start/app/google-services.json
في الخطوة الأخيرة من هذا الدرس العملي، ستتعلّم كيفية إنشاء مشروع حقيقي على Firebase وتطبيق Android على Firebase حتى تتمكّن من استبدال ملف JSON التجريبي هذا بإعداداتك الخاصة.
تشغيل التطبيق
بعد استيراد المشروع إلى "استوديو Android" وإضافة ملف JSON لإعدادات Firebase، ستكون جاهزًا لتشغيل التطبيق للمرة الأولى.
- ابدأ تشغيل "محاكي Android".
- في "استوديو Android"، انقر على تشغيل (
) في شريط الأدوات.
يجب أن يتم تشغيل التطبيق على "محاكي Android". في هذه المرحلة، من المفترض أن تظهر لك قائمة رسائل فارغة، ولن تتمكّن من إرسال الرسائل وتلقّيها. في الخطوة التالية من هذا الدرس العملي، ستصادق على المستخدمين ليتمكّنوا من استخدام تطبيق Friendly Chat.
6. تفعيل المصادقة
سيستخدم هذا التطبيق "قاعدة بيانات Firebase في الوقت الفعلي" لتخزين جميع رسائل المحادثة. قبل إضافة البيانات، يجب التأكّد من أنّ التطبيق آمن وأنّه يمكن للمستخدمين الذين تمّت المصادقة عليهم فقط نشر الرسائل. في هذه الخطوة، سنفعّل خدمة "مصادقة Firebase" ونضبط "قواعد الأمان" في "قاعدة بيانات الوقت الفعلي".
إضافة وظيفة تسجيل الدخول الأساسية
بعد ذلك، سنضيف بعض رموز مصادقة Firebase الأساسية إلى التطبيق لرصد المستخدمين وتنفيذ شاشة تسجيل الدخول.
التحقّق من المستخدم الحالي
أضِف أولاً متغيّر المثيل التالي إلى الفئة MainActivity.kt:
MainActivity.kt
// Firebase instance variables
private lateinit var auth: FirebaseAuth
لنعدّل الآن MainActivity لإعادة توجيه المستخدم إلى شاشة تسجيل الدخول كلما فتح التطبيق ولم يتم إثبات هويته. أضِف ما يلي إلى طريقة onCreate() بعد ربط binding بالعرض:
MainActivity.kt
// Initialize Firebase Auth and check if the user is signed in
auth = Firebase.auth
if (auth.currentUser == null) {
// Not signed in, launch the Sign In activity
startActivity(Intent(this, SignInActivity::class.java))
finish()
return
}
نريد أيضًا التحقّق مما إذا كان المستخدم مسجّلاً الدخول أثناء onStart():
MainActivity.kt
public override fun onStart() {
super.onStart()
// Check if user is signed in.
if (auth.currentUser == null) {
// Not signed in, launch the Sign In activity
startActivity(Intent(this, SignInActivity::class.java))
finish()
return
}
}
بعد ذلك، نفِّذ الطريقتَين getUserPhotoUrl() وgetUserName() لعرض المعلومات المناسبة عن مستخدم Firebase الذي تمّت مصادقته حاليًا:
MainActivity.kt
private fun getPhotoUrl(): String? {
val user = auth.currentUser
return user?.photoUrl?.toString()
}
private fun getUserName(): String? {
val user = auth.currentUser
return if (user != null) {
user.displayName
} else ANONYMOUS
}
بعد ذلك، نفِّذ طريقة signOut() للتعامل مع زر تسجيل الخروج:
MainActivity.kt
private fun signOut() {
AuthUI.getInstance().signOut()
startActivity(Intent(this, SignInActivity::class.java))
finish()
}
الآن، لدينا كل المنطق اللازم لتوجيه المستخدم إلى شاشة تسجيل الدخول عند الضرورة. بعد ذلك، علينا تنفيذ شاشة تسجيل الدخول للمصادقة على المستخدمين بشكلٍ صحيح.
تنفيذ شاشة تسجيل الدخول
افتح الملف SignInActivity.kt. يتم هنا استخدام زر بسيط لتسجيل الدخول من أجل بدء عملية المصادقة. في هذا القسم، ستستخدم FirebaseUI لتنفيذ منطق تسجيل الدخول.
أضِف متغيّر مثيل Auth في الفئة SignInActivity ضمن التعليق // Firebase instance variables:
SignInActivity.kt
// Firebase instance variables
private lateinit var auth: FirebaseAuth
بعد ذلك، عدِّل طريقة onCreate() لإعداد Firebase بالطريقة نفسها التي اتّبعتها في MainActivity:
SignInActivity.kt
// Initialize FirebaseAuth
auth = Firebase.auth
أضِف حقل ActivityResultLauncher إلى SignInActivity:
SignInActivity.kt
// ADD THIS
private val signIn: ActivityResultLauncher<Intent> =
registerForActivityResult(FirebaseAuthUIActivityResultContract(), this::onSignInResult)
override fun onCreate(savedInstanceState: Bundle?) {
// ...
}
بعد ذلك، عدِّل طريقة onStart() لبدء عملية تسجيل الدخول في FirebaseUI:
SignInActivity.kt
public override fun onStart() {
super.onStart()
// If there is no signed in user, launch FirebaseUI
// Otherwise head to MainActivity
if (Firebase.auth.currentUser == null) {
// Sign in with FirebaseUI, see docs for more details:
// https://firebase.google.com/docs/auth/android/firebaseui
val signInIntent = AuthUI.getInstance()
.createSignInIntentBuilder()
.setLogo(R.mipmap.ic_launcher)
.setAvailableProviders(listOf(
AuthUI.IdpConfig.EmailBuilder().build(),
AuthUI.IdpConfig.GoogleBuilder().build(),
))
.build()
signIn.launch(signInIntent)
} else {
goToMainActivity()
}
}
بعد ذلك، نفِّذ طريقة onSignInResult للتعامل مع نتيجة تسجيل الدخول. إذا كانت نتيجة تسجيل الدخول ناجحة، انتقِل إلى MainActivity:
SignInActivity.kt
private fun onSignInResult(result: FirebaseAuthUIAuthenticationResult) {
if (result.resultCode == RESULT_OK) {
Log.d(TAG, "Sign in successful!")
goToMainActivity()
} else {
Toast.makeText(
this,
"There was an error signing in",
Toast.LENGTH_LONG).show()
val response = result.idpResponse
if (response == null) {
Log.w(TAG, "Sign in canceled")
} else {
Log.w(TAG, "Sign in error", response.error)
}
}
}
وهذا كل ما في الأمر! لقد نفّذت المصادقة باستخدام FirebaseUI ببضع استدعاءات للأساليب وبدون الحاجة إلى إدارة أي إعدادات من جهة الخادم.
اختبار عملك
شغِّل التطبيق على "محاكي Android". من المفترض أن يتم توجيهك على الفور إلى شاشة تسجيل الدخول. انقر على الزر تسجيل الدخول باستخدام البريد الإلكتروني، ثم أنشئ حسابًا. إذا تم تنفيذ كل شيء بشكل صحيح، سيتم توجيهك إلى شاشة المراسلة.
بعد تسجيل الدخول، افتح واجهة مستخدم "مجموعة أدوات محاكي Firebase" في المتصفّح، ثم انقر على علامة التبويب المصادقة للاطّلاع على حساب المستخدم الذي سجّل الدخول أولاً.

7. قراءة الرسائل
في هذه الخطوة، سنضيف وظيفة لقراءة الرسائل المخزّنة في قاعدة بيانات الوقت الفعلي وعرضها.
استيراد نماذج الرسائل
- في واجهة مستخدم "مجموعة أدوات محاكاة Firebase"، اختَر علامة التبويب قاعدة بيانات الوقت الفعلي.
- اسحب ملف
initial_messages.jsonوأفلِته من نسختك المحلية من مستودع Codelab إلى "عارض البيانات".

يجب أن تتضمّن قاعدة البيانات الآن بضع رسائل ضمن العقدة messages.
قراءة البيانات
مزامنة الرسائل
في هذا القسم، نضيف رمزًا برمجيًا يعمل على مزامنة الرسائل المضافة حديثًا مع واجهة مستخدم التطبيق من خلال:
- إعداد قاعدة بيانات Firebase في الوقت الفعلي وإضافة متتبِّع للتعامل مع التغييرات التي يتم إجراؤها على البيانات
- تعديل أداة
RecyclerViewحتى يتم عرض الرسائل الجديدة - إضافة متغيرات مثيل قاعدة البيانات مع متغيرات مثيل Firebase الأخرى في الفئة
MainActivity:
MainActivity.kt
// Firebase instance variables
// ...
private lateinit var db: FirebaseDatabase
private lateinit var adapter: FriendlyMessageAdapter
عدِّل طريقة onCreate() في MainActivity ضمن التعليق // Initialize Realtime Database and FirebaseRecyclerAdapter باستخدام الرمز المحدّد أدناه. يضيف هذا الرمز جميع الرسائل الحالية من "قاعدة بيانات الوقت الفعلي"، ثم يستمع إلى إدخالات العناصر الفرعية الجديدة ضمن المسار messages في "قاعدة بيانات Firebase في الوقت الفعلي". تضيف هذه السمة عنصرًا جديدًا إلى واجهة المستخدم لكل رسالة:
MainActivity.kt
// Initialize Realtime Database
db = Firebase.database
val messagesRef = db.reference.child(MESSAGES_CHILD)
// The FirebaseRecyclerAdapter class and options come from the FirebaseUI library
// See: https://github.com/firebase/FirebaseUI-Android
val options = FirebaseRecyclerOptions.Builder<FriendlyMessage>()
.setQuery(messagesRef, FriendlyMessage::class.java)
.build()
adapter = FriendlyMessageAdapter(options, getUserName())
binding.progressBar.visibility = ProgressBar.INVISIBLE
manager = LinearLayoutManager(this)
manager.stackFromEnd = true
binding.messageRecyclerView.layoutManager = manager
binding.messageRecyclerView.adapter = adapter
// Scroll down when a new message arrives
// See MyScrollToBottomObserver for details
adapter.registerAdapterDataObserver(
MyScrollToBottomObserver(binding.messageRecyclerView, adapter, manager)
)
بعد ذلك، نفِّذ طريقة bind() في الفئة FriendlyMessageAdapter.kt ضمن الفئة الداخلية MessageViewHolder():
FriendlyMessageAdapter.kt
inner class MessageViewHolder(private val binding: MessageBinding) : ViewHolder(binding.root) {
fun bind(item: FriendlyMessage) {
binding.messageTextView.text = item.text
setTextColor(item.name, binding.messageTextView)
binding.messengerTextView.text = if (item.name == null) ANONYMOUS else item.name
if (item.photoUrl != null) {
loadImageIntoView(binding.messengerImageView, item.photoUrl!!)
} else {
binding.messengerImageView.setImageResource(R.drawable.ic_account_circle_black_36dp)
}
}
...
}
نحتاج أيضًا إلى عرض الرسائل التي هي عبارة عن صور، لذا نفّذ أيضًا طريقة bind() داخل الفئة الداخلية ImageMessageViewHolder():
FriendlyMessageAdapter.kt
inner class ImageMessageViewHolder(private val binding: ImageMessageBinding) :
ViewHolder(binding.root) {
fun bind(item: FriendlyMessage) {
loadImageIntoView(binding.messageImageView, item.imageUrl!!)
binding.messengerTextView.text = if (item.name == null) ANONYMOUS else item.name
if (item.photoUrl != null) {
loadImageIntoView(binding.messengerImageView, item.photoUrl!!)
} else {
binding.messengerImageView.setImageResource(R.drawable.ic_account_circle_black_36dp)
}
}
}
أخيرًا، ارجع إلى MainActivity، وابدأ في الاستماع إلى آخر الأخبار من قاعدة بيانات Firebase في الوقت الفعلي وأوقِف هذه العملية. عدِّل الطريقتَين onPause() وonResume() في MainActivity كما هو موضّح أدناه:
MainActivity.kt
public override fun onPause() {
adapter.stopListening()
super.onPause()
}
public override fun onResume() {
super.onResume()
adapter.startListening()
}
اختبار مزامنة الرسائل
- انقر على تشغيل (
). - في واجهة مستخدم مجموعة أدوات المحاكاة، ارجع إلى علامة التبويب قاعدة بيانات الوقت الفعلي، ثم أضِف رسالة جديدة يدويًا. تأكَّد من ظهور الرسالة في تطبيق Android باتّباع الخطوات التالية:

تهانينا، لقد أضفت للتو قاعدة بيانات آنية الاستجابة إلى تطبيقك.
8. إرسال الرسائل
تنفيذ عملية إرسال الرسائل النصية
في هذا القسم، ستضيف إمكانية إرسال رسائل نصية إلى مستخدمي التطبيق. تستمع مقتطفة الرمز البرمجي أدناه إلى أحداث النقر على زر الإرسال، وتنشئ عنصر FriendlyMessage جديدًا يتضمّن محتوى حقل الرسالة، وتدفع الرسالة إلى قاعدة البيانات. يضيف الإجراء push() معرّفًا تم إنشاؤه تلقائيًا إلى مسار العنصر الذي تم إرساله. تكون أرقام التعريف هذه متسلسلة، ما يضمن إضافة الرسائل الجديدة إلى نهاية القائمة.
عدِّل أداة معالجة النقرات لزر الإرسال في الطريقة onCreate() في الفئة MainActivity. يظهر هذا الرمز في أسفل طريقة الدفع onCreate(). عدِّل onClick() النص الأساسي ليتطابق مع الرمز أدناه:
MainActivity.kt
// Disable the send button when there's no text in the input field
// See MyButtonObserver for details
binding.messageEditText.addTextChangedListener(MyButtonObserver(binding.sendButton))
// When the send button is clicked, send a text message
binding.sendButton.setOnClickListener {
val friendlyMessage = FriendlyMessage(
binding.messageEditText.text.toString(),
getUserName(),
getPhotoUrl(),
null /* no image */
)
db.reference.child(MESSAGES_CHILD).push().setValue(friendlyMessage)
binding.messageEditText.setText("")
}
تنفيذ عملية إرسال رسائل الصور
في هذا القسم، ستضيف إمكانية إرسال رسائل تتضمّن صورًا لمستخدمي التطبيق. يتم إنشاء رسالة صورة باتّباع الخطوات التالية:
- اختيار صورة
- التعامل مع اختيار الصور
- كتابة رسالة صورة مؤقتة إلى قاعدة بيانات الوقت الفعلي
- بدء تحميل الصورة المحدّدة
- تعديل عنوان URL لرسالة الصورة إلى عنوان URL الخاص بالصورة التي تم تحميلها، وذلك بعد اكتمال عملية التحميل
اختيار صورة
لإضافة صور، يستخدم هذا الدرس التطبيقي مساحة تخزين سحابية لـ Firebase. Cloud Storage هو مكان مناسب لتخزين البيانات الثنائية لتطبيقك.
اختيار صورة الاسم المعرّف وكتابة رسالة مؤقتة
بعد أن يختار المستخدم صورة، يتم تشغيل أداة اختيار الصور Intent. يتم تنفيذ ذلك تلقائيًا في الرمز في نهاية طريقة onCreate(). عند الانتهاء، يتم استدعاء طريقة onImageSelected() في MainActivity. باستخدام مقتطف الرمز البرمجي أدناه، ستكتب رسالة تتضمّن عنوان URL مؤقتًا للصورة في قاعدة البيانات يشير إلى أنّه يتم تحميل الصورة.
MainActivity.kt
private fun onImageSelected(uri: Uri) {
Log.d(TAG, "Uri: $uri")
val user = auth.currentUser
val tempMessage = FriendlyMessage(null, getUserName(), getPhotoUrl(), LOADING_IMAGE_URL)
db.reference
.child(MESSAGES_CHILD)
.push()
.setValue(
tempMessage,
DatabaseReference.CompletionListener { databaseError, databaseReference ->
if (databaseError != null) {
Log.w(
TAG, "Unable to write message to database.",
databaseError.toException()
)
return@CompletionListener
}
// Build a StorageReference and then upload the file
val key = databaseReference.key
val storageReference = Firebase.storage
.getReference(user!!.uid)
.child(key!!)
.child(uri.lastPathSegment!!)
putImageInStorage(storageReference, uri, key)
})
}
تحميل صورة وتعديل الرسالة
أضِف الطريقة putImageInStorage() إلى MainActivity. يتم استدعاؤه في onImageSelected() لبدء تحميل الصورة المحدّدة. بعد اكتمال التحميل، عليك تعديل الرسالة لاستخدام الصورة المناسبة.
MainActivity.kt
private fun putImageInStorage(storageReference: StorageReference, uri: Uri, key: String?) {
// First upload the image to Cloud Storage
storageReference.putFile(uri)
.addOnSuccessListener(
this
) { taskSnapshot -> // After the image loads, get a public downloadUrl for the image
// and add it to the message.
taskSnapshot.metadata!!.reference!!.downloadUrl
.addOnSuccessListener { uri ->
val friendlyMessage =
FriendlyMessage(null, getUserName(), getPhotoUrl(), uri.toString())
db.reference
.child(MESSAGES_CHILD)
.child(key!!)
.setValue(friendlyMessage)
}
}
.addOnFailureListener(this) { e ->
Log.w(
TAG,
"Image upload task was unsuccessful.",
e
)
}
}
اختبار إرسال الرسائل
- في "استوديو Android"، انقر على الزر
تشغيل. - في "محاكي Android"، أدخِل رسالة، ثم انقر على زر الإرسال. يجب أن تظهر الرسالة الجديدة في واجهة مستخدم التطبيق وفي واجهة مستخدم "مجموعة أدوات المحاكاة" في Firebase.
- في "محاكي Android"، انقر على صورة "+" لاختيار صورة من جهازك. يجب أن تظهر الرسالة الجديدة أولاً مع صورة عنصر نائب، ثم مع الصورة المحدّدة بعد اكتمال عملية تحميل الصورة. يجب أن تظهر الرسالة الجديدة أيضًا في واجهة مستخدم مجموعة أدوات المحاكاة، وتحديدًا كعنصر في علامة التبويب قاعدة بيانات الوقت الفعلي وككائن ثنائي كبير في علامة التبويب Storage.
9. تهانينا!
لقد أنشأت للتو تطبيق محادثة في الوقت الفعلي باستخدام Firebase.
ما تعلّمته
- مصادقة Firebase
- قاعدة بيانات Firebase في الوقت الفعلي
- التخزين في السحابة الإلكترونية لبرنامج Firebase
بعد ذلك، جرِّب استخدام ما تعلّمته في هذا الدرس التطبيقي حول الترميز لإضافة Firebase إلى تطبيق Android الخاص بك. لمزيد من المعلومات عن Firebase، يُرجى الانتقال إلى firebase.google.com.
إذا أردت التعرّف على كيفية إعداد مشروع Firebase حقيقي واستخدام موارد حقيقية على Firebase (بدلاً من مشروع تجريبي وموارد محاكاة فقط)، انتقِل إلى الخطوة التالية.
ملاحظة: حتى بعد إعداد مشروع Firebase حقيقي، ننصحك باستخدام "مجموعة أدوات المحاكاة المحلية لـ Firebase" في عملية التطوير والاختبار، خاصةً عند البدء في إنشاء تطبيق حقيقي.
10. اختياري: إنشاء مشروع Firebase وإعداده
في هذه الخطوة، ستنشئ مشروع Firebase حقيقيًا وتطبيق Android على Firebase لاستخدامهما مع هذا الدرس العملي. ستضيف أيضًا إعدادات Firebase الخاصة بتطبيقك إلى تطبيقك. وأخيرًا، ستُعدّ موارد Firebase الحقيقية لاستخدامها مع تطبيقك.
إنشاء مشروع Firebase
- سجِّل الدخول إلى وحدة تحكّم Firebase باستخدام حساب Google.
- انقر على الزر لإنشاء مشروع جديد، ثم أدخِل اسم المشروع (على سبيل المثال،
FriendlyChat).
- انقر على متابعة.
- إذا طُلب منك ذلك، راجِع بنود Firebase واقبلها، ثم انقر على متابعة.
- (اختياري) فعِّل ميزة "المساعدة المستندة إلى الذكاء الاصطناعي" في وحدة تحكّم Firebase (المعروفة باسم "Gemini في Firebase").
- في هذا الدرس العملي، لا تحتاج إلى "إحصاءات Google"، لذا أوقِف خيار "إحصاءات Google".
- انقر على إنشاء مشروع، وانتظِر إلى أن يتم توفير مشروعك، ثم انقر على متابعة.
ترقية خطة أسعار Firebase
لاستخدام مساحة تخزين سحابية لـ Firebase، يجب أن يكون مشروع Firebase الخاص بك ضمن خطة التسعير "الدفع حسب الاستخدام" (Blaze)، ما يعني أنّه مرتبط بحساب فوترة على Cloud.
- يتطلّب حساب الفوترة في Cloud طريقة دفع، مثل بطاقة الائتمان.
- إذا كنت حديث العهد باستخدام Firebase وGoogle Cloud، تحقّق ممّا إذا كنت مؤهَّلاً للحصول على رصيد بقيمة 300 دولار أمريكي وحساب فوترة في Cloud ضمن "الفترة التجريبية المجانية".
- إذا كنت تجري هذا الدرس التطبيقي حول الترميز كجزء من حدث، اسأل المنظّم عمّا إذا كانت هناك أي أرصدة Cloud متاحة.
لترقية مشروعك إلى خطة Blaze، اتّبِع الخطوات التالية:
- في "وحدة تحكّم Firebase"، اختَر ترقية خطتك.
- اختَر خطة Blaze. اتّبِع التعليمات الظاهرة على الشاشة لربط حساب فوترة على Cloud بمشروعك.
إذا كان عليك إنشاء حساب فوترة على Cloud كجزء من عملية الترقية هذه، قد تحتاج إلى الرجوع إلى مسار الترقية في وحدة تحكّم Firebase لإكمال عملية الترقية.
إضافة Firebase إلى مشروع Android
في وحدة تحكّم Firebase، اتّبِع الخطوات التالية لتسجيل مشروع Android في مشروعك على Firebase:
- من شاشة النظرة العامة لمشروعك الجديد، انقر على رمز Android لبدء سير عمل الإعداد:

- في الشاشة التالية، أدخِل
com.google.firebase.codelab.friendlychatكاسم حزمة تطبيقك. - انقر على تسجيل التطبيق، ثم انقر على تنزيل ملف google-services.json لتنزيل ملف إعداد Firebase.
- انسخ ملف
google-services.jsonإلى الدليلappفي مشروع Android. - تخطَّ الخطوات التالية المعروضة في سير عمل الإعداد الخاص بوحدة التحكّم (تم تنفيذها لك من قبل في مشروع
build-android-start). - تأكَّد من توفّر جميع الاعتماديات لتطبيقك من خلال مزامنة مشروعك مع ملفات Gradle. من شريط أدوات "استوديو Android"، اختَر ملف > مزامنة المشروع مع ملفات Gradle. قد تحتاج أيضًا إلى تنفيذ إنشاء/تنظيف المشروع وإنشاء/إعادة إنشاء المشروع لتطبيق تغييرات الإعداد.
ضبط إعدادات خدمة "مصادقة Firebase"
قبل أن يتمكّن تطبيقك من الوصول إلى واجهات برمجة التطبيقات في خدمة "مصادقة Firebase" نيابةً عن المستخدمين، عليك تفعيل خدمة "مصادقة Firebase" وموفّري خدمات تسجيل الدخول الذين تريد استخدامهم في تطبيقك.
- في وحدة تحكّم Firebase، اختَر المصادقة من لوحة التنقّل على يمين الصفحة.
- انقر على علامة التبويب طريقة تسجيل الدخول.
- انقر على البريد الإلكتروني/كلمة المرور، ثمّ فعِّل مفتاح التبديل (أزرق).
- انقر على Google، ثم فعِّل الخيار (أزرق) واضبط عنوان بريد إلكتروني مخصّصًا لدعم المشروع.
إذا ظهرت لك أخطاء لاحقًا في هذا الدرس التطبيقي حول الترميز مع الرسالة "CONFIGURATION_NOT_FOUND"، ارجع إلى هذه الخطوة وتحقّق من عملك.
قد تحتاج إلى تحديد ملف SHA المرجعي لتطبيقك من أجل استخدام ميزة "تسجيل الدخول باستخدام حساب Google". يمكنك إجراء ذلك في صفحة الإعدادات في وحدة تحكّم Firebase. راجِع مقالة مصادقة عميلك لمعرفة تفاصيل حول كيفية الحصول على الملف المرجعي SHA لتطبيقك.
إعداد قاعدة بيانات الوقت الفعلي
يخزّن التطبيق في هذا الدرس التطبيقي حول الترميز رسائل المحادثة في "قاعدة بيانات Firebase في الوقت الفعلي". في هذا القسم، سننشئ قاعدة بيانات ونضبط إعدادات الأمان الخاصة بها من خلال لغة إعدادات JSON تُسمى "قواعد الأمان في Firebase".
- في اللوحة اليمنى من "وحدة تحكّم Firebase"، وسِّع إنشاء، ثمّ اختَر قاعدة بيانات الوقت الفعلي.
- انقر على إنشاء قاعدة بيانات.
- اختَر موقعًا لقاعدة البيانات، ثم انقر على التالي.
بالنسبة إلى تطبيق حقيقي، عليك اختيار موقع جغرافي قريب من المستخدمين. - انقر على بدء التشغيل في وضع الاختبار. اقرأ بيان إخلاء المسؤولية عن قواعد الأمان.
في الخطوات التالية من هذا الدرس العملي، ستضيف قواعد الأمان لتأمين بياناتك. لا توزِّع تطبيقًا أو تعرضه بشكل علني بدون إضافة "قواعد الأمان" لقاعدة البيانات. - انقر على إنشاء.
- بعد إنشاء مثيل قاعدة البيانات، اختَر علامة التبويب القواعد، ثم عدِّل إعدادات القواعد بما يلي:
{ "rules": { "messages": { ".read": "auth.uid != null", ".write": "auth.uid != null" } } }
لمزيد من المعلومات حول طريقة عمل "قواعد الأمان" (بما في ذلك المستندات حول المتغيّر "auth")، راجِع مستندات أمان قاعدة بيانات الوقت الفعلي.
إعداد "مساحة تخزين سحابية لـ Firebase"
- في اللوحة اليمنى من وحدة تحكّم Firebase، وسِّع إنشاء، ثم اختَر مساحة التخزين.
- انقر على البدء.
- اختَر موقعًا جغرافيًا لحزمة التخزين التلقائية.
يمكن للحِزم فيUS-WEST1وUS-CENTRAL1وUS-EAST1الاستفادة من الفئة"دائمًا مجانية" في Google Cloud Storage. تخضع الحِزم في جميع المواقع الجغرافية الأخرى لأسعار واستخدام Google Cloud Storage. - انقر على بدء التشغيل في وضع الاختبار. اقرأ بيان إخلاء المسؤولية حول قواعد الأمان.
في وقت لاحق من هذا الدرس العملي، ستضيف قواعد أمان لحماية بياناتك. لا توزّع تطبيقًا أو تعرضه للجميع بدون إضافة "قواعد الأمان" لحزمة Cloud Storage. - انقر على إنشاء.
الربط بموارد Firebase
في خطوة سابقة من هذا الدرس التطبيقي حول الترميز، أضفت ما يلي إلى MainActivity.kt. ربطت كتلة التعليمات البرمجية الشرطية هذه مشروع Android بـ "مجموعة أدوات محاكاة Firebase".
// REMOVE OR DISABLE THIS
if (BuildConfig.DEBUG) {
Firebase.database.useEmulator("10.0.2.2", 9000)
Firebase.auth.useEmulator("10.0.2.2", 9099)
Firebase.storage.useEmulator("10.0.2.2", 9199)
}
إذا كنت تريد ربط تطبيقك بمشروع فعلي جديد على Firebase وموارد فعلية على Firebase، يمكنك إزالة هذا الحظر أو تشغيل تطبيقك في وضع الإصدار لكي تكون قيمة BuildConfig.DEBUG هي false.