1. نظرة عامة
صورة: تطبيق Friendly Chat يعمل.
مرحبًا بك في برنامج Friendly Chat التعليمي. في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية استخدام منصة Firebase لإنشاء تطبيق دردشة على Android.
أهداف الدورة التعليمية
- كيفية استخدام خدمة "مصادقة Firebase" للسماح للمستخدمين بتسجيل الدخول
- كيفية مزامنة البيانات باستخدام "قاعدة بيانات Firebase في الوقت الفعلي"
- كيفية تخزين الملفات الثنائية في "مساحة تخزين سحابية لـ Firebase"
- كيفية استخدام "مجموعة أدوات المحاكاة المحلية لمنصة Firebase" لتطوير تطبيق Android باستخدام Firebase
المتطلبات
- أحدث إصدار من استوديو Android
- Android Emulator يعمل بالإصدار 5.0 من نظام التشغيل Android أو إصدار أحدث
- الإصدار 10 من Node.js أو إصدار أحدث (لاستخدام Emulator Suite)
- الإصدار 8 من Java أو إصدار أحدث لتثبيت Java، اتّبِع هذه التعليمات، وللتحقّق من إصدارك، شغِّل
java -version
. - الإلمام بلغة البرمجة Kotlin
2. الحصول على الرمز النموذجي
إنشاء نسخة طبق الأصل من المستودع
استنسِخ مستودع GitHub من سطر الأوامر:
$ git clone https://github.com/firebase/codelab-friendlychat-android
الاستيراد إلى "استوديو Android"
في "استوديو Android"، انقر على ملف > فتح، ثم اختَر دليل 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 وRealtime Database وCloud Storage محليًا. يوفّر ذلك بيئة تطوير محلية آمنة وسريعة وبدون تكلفة لإنشاء تطبيقك.
تثبيت Firebase CLI
عليك أولاً تثبيت واجهة سطر الأوامر في Firebase. إذا كنت تستخدم نظام التشغيل 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 Authentication الأساسية إلى التطبيق لرصد المستخدمين وتنفيذ شاشة تسجيل الدخول.
التحقّق من المستخدم الحالي
أضِف أولاً متغيّر المثيل التالي إلى الفئة 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. قراءة الرسائل
في هذه الخطوة، سنضيف وظيفة لقراءة الرسائل المخزّنة في Realtime Database وعرضها.
استيراد نماذج الرسائل
- في واجهة مستخدم "مجموعة أدوات المحاكي في Firebase"، اختَر علامة التبويب Realtime Database.
- اسحب ملف
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)
)
بعد ذلك، في الفئة FriendlyMessageAdapter.kt
، نفِّذ الطريقة bind()
ضمن الفئة الداخلية 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()
}
اختبار مزامنة الرسائل
- انقر على تشغيل (
).
- في واجهة مستخدم Emulator Suite، ارجع إلى علامة التبويب Realtime Database، ثم أضِف رسالة جديدة يدويًا. تأكَّد من ظهور الرسالة في تطبيق 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("")
}
تنفيذ عملية إرسال رسائل الصور
في هذا القسم، ستضيف إمكانية إرسال رسائل تتضمّن صورًا لمستخدمي التطبيق. يتم إنشاء رسالة صورة باتّباع الخطوات التالية:
- اختيار صورة
- التعامل مع اختيار الصور
- كتابة رسالة صورة مؤقتة إلى Realtime Database
- بدء تحميل الصورة المحدّدة
- تعديل عنوان URL لرسالة الصورة إلى عنوان URL للصورة التي تم تحميلها، وذلك بعد اكتمال عملية التحميل
اختيار صورة
تستخدم ورشة العمل البرمجية هذه خدمة Cloud Storage for 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"، انقر على صورة "+" لاختيار صورة من جهازك. يجب أن تظهر الرسالة الجديدة أولاً مع صورة عنصر نائب، ثم مع الصورة المحدّدة بعد اكتمال عملية تحميل الصورة. يجب أن تظهر الرسالة الجديدة أيضًا في واجهة مستخدم Emulator Suite، وتحديدًا كعنصر في علامة التبويب Realtime Database وككائن ثنائي كبير في علامة التبويب 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
لاستخدام Cloud Storage for Firebase، يجب أن يكون مشروعك على Firebase ضمن خطة التسعير "الدفع حسب الاستخدام" (Blaze)، ما يعني أنّه مرتبط بحساب فوترة Cloud.
- يتطلّب حساب الفوترة في Cloud طريقة دفع، مثل بطاقة الائتمان.
- إذا كنت حديث العهد باستخدام Firebase وGoogle Cloud، تحقَّق ممّا إذا كنت مؤهَّلاً للحصول على رصيد بقيمة 300 دولار أمريكي وحساب فوترة على Cloud في الفترة التجريبية المجانية.
- إذا كنت تجري هذا الدرس العملي المبرمَج كجزء من حدث، اسأل المنظِّم عمّا إذا كانت هناك أي أرصدة في السحابة الإلكترونية متاحة.
لترقية مشروعك إلى خطة Blaze، اتّبِع الخطوات التالية:
- في "وحدة تحكّم Firebase"، اختَر ترقية خطتك.
- اختَر خطة Blaze. اتّبِع التعليمات الظاهرة على الشاشة لربط حساب فوترة على Cloud بمشروعك.
إذا احتجت إلى إنشاء حساب فوترة على Cloud كجزء من عملية الترقية هذه، قد تحتاج إلى الرجوع إلى مسار الترقية في وحدة تحكّم Firebase لإكمال عملية الترقية.
إضافة Firebase إلى مشروع Android
قبل البدء في هذه الخطوة، احصل على تجزئة SHA1 لتطبيقك. شغِّل الأمر التالي من دليل build-android-start
المحلي لتحديد SHA1 لمفتاح تصحيح الأخطاء:
./gradlew signingReport Store: /Users/<username>/.android/debug.keystore Alias: AndroidDebugKey MD5: A5:88:41:04:8F:06:59:6A:AE:33:76:87:AA:AD:19:23 SHA1: A7:89:F5:06:A8:07:A1:22:EC:90:6A:A6:EA:C3:D4:8B:3A:30:AB:18 SHA-256: 05:A2:2A:35:EE:F2:51:23:72:4D:72:67:A5:6A:8A:58:22:2C:00:A6:AB:F6:45:D5:A1:82:D8:90:A4:69:C8:FE Valid until: Wednesday, August 10, 2044
من المفترَض أن تظهر لك بعض النتائج المشابهة لما ورد أعلاه. السطر المهم هو رمز التجزئة SHA1
. إذا لم تتمكّن من العثور على تجزئة SHA1، يُرجى الاطّلاع على هذه الصفحة للحصول على مزيد من المعلومات.
ارجع إلى "وحدة تحكّم Firebase" واتّبِع الخطوات التالية لتسجيل مشروع Android في مشروعك على Firebase:
- من شاشة النظرة العامة لمشروعك الجديد، انقر على رمز Android لبدء عملية الإعداد:
- في الشاشة التالية، أدخِل
com.google.firebase.codelab.friendlychat
كاسم حزمة تطبيقك. - انقر على تسجيل التطبيق، ثم انقر على تنزيل ملف google-services.json لتنزيل ملف إعدادات Firebase.
- انسخ ملف
google-services.json
إلى الدليلapp
في مشروع Android. - تخطَّ الخطوات التالية المعروضة في سير عمل الإعداد الخاص بوحدة التحكّم (تم تنفيذها مسبقًا في مشروع
build-android-start
). - تأكَّد من توفّر جميع التبعيات لتطبيقك من خلال مزامنة مشروعك مع ملفات Gradle. من شريط أدوات "استوديو Android"، اختَر ملف (File) > مزامنة المشروع مع ملفات Gradle (Sync Project with Gradle Files). قد تحتاج أيضًا إلى تنفيذ إنشاء/تنظيف المشروع وإنشاء/إعادة إنشاء المشروع لتطبيق تغييرات الإعداد.
ضبط إعدادات خدمة "مصادقة Firebase"
قبل أن يتمكّن تطبيقك من الوصول إلى واجهات برمجة التطبيقات الخاصة بخدمة "المصادقة في Firebase" نيابةً عن المستخدمين، عليك تفعيل خدمة "المصادقة في Firebase" وموفّري خدمات تسجيل الدخول الذين تريد استخدامهم في تطبيقك.
- في وحدة تحكّم Firebase، اختَر المصادقة من لوحة التنقّل اليمنى.
- انقر على علامة التبويب طريقة تسجيل الدخول.
- انقر على البريد الإلكتروني/كلمة المرور، ثمّ فعِّل مفتاح التبديل (أزرق).
- انقر على Google، ثم فعِّل الخيار (أزرق) واضبط عنوان بريد إلكتروني مخصّصًا لدعم المشروع.
إذا ظهرت لك أخطاء لاحقًا في هذا الدرس العملي مع الرسالة "CONFIGURATION_NOT_FOUND"، ارجع إلى هذه الخطوة وتحقّق من عملك.
إعداد قاعدة بيانات الوقت الفعلي
يخزّن التطبيق في هذا الدرس النموذجي رسائل المحادثة في "قاعدة بيانات Firebase في الوقت الفعلي". في هذا القسم، سننشئ قاعدة بيانات ونضبط إعدادات الأمان الخاصة بها باستخدام لغة إعدادات JSON تُسمى "قواعد الأمان في Firebase".
- في اللوحة اليمنى من "وحدة تحكّم Firebase"، وسِّع إنشاء، ثم اختَر Realtime Database.
- انقر على إنشاء قاعدة بيانات.
- اختَر موقعًا لقاعدة البيانات، ثم انقر على التالي.
بالنسبة إلى تطبيق حقيقي، عليك اختيار موقع جغرافي قريب من المستخدمين. - انقر على البدء في وضع الاختبار. اقرأ بيان إخلاء المسؤولية عن قواعد الأمان.
في الخطوات التالية من هذا الدرس العملي، ستضيف قواعد الأمان لتأمين بياناتك. لا توزِّع تطبيقًا أو تعرضه بشكل علني بدون إضافة "قواعد الأمان" لقاعدة البيانات. - انقر على إنشاء.
- بعد إنشاء مثيل قاعدة البيانات، اختَر علامة التبويب القواعد، ثم عدِّل إعدادات القواعد بما يلي:
{ "rules": { "messages": { ".read": "auth.uid != null", ".write": "auth.uid != null" } } }
لمزيد من المعلومات حول طريقة عمل "قواعد الأمان" (بما في ذلك المستندات حول المتغيّر "auth")، راجِع مستندات أمان Realtime Database.
إعداد "مساحة تخزين سحابية لـ Firebase"
- في اللوحة اليمنى من وحدة تحكّم Firebase، وسِّع إنشاء، ثم اختَر مساحة التخزين.
- انقر على البدء.
- اختَر موقعًا جغرافيًا لحزمة Storage التلقائية.
يمكن للحِزم في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
.