Firebase Android Codelab - إنشاء دردشة ودية

1. نظرة عامة

لقطة شاشة

الصورة: تطبيق الدردشة الودية العامل.

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

ما ستتعلمه

  • كيفية استخدام مصادقة Firebase للسماح للمستخدمين بتسجيل الدخول.
  • كيفية مزامنة البيانات باستخدام قاعدة بيانات Firebase Realtime.
  • كيفية تخزين الملفات الثنائية في Cloud Storage لـ Firebase.
  • كيفية استخدام Firebase Local Emulator Suite لتطوير تطبيق Android باستخدام Firebase.

ماذا ستحتاج

  • أحدث إصدار من أندرويد ستوديو .
  • محاكي Android مع Android 5.0+.
  • Node.js الإصدار 10 أو أعلى (لاستخدام Emulator Suite).
  • جافا 8 أو أعلى. لتثبيت Java، استخدم هذه التعليمات ؛ للتحقق من الإصدار الخاص بك، قم بتشغيل java -version .
  • - الإلمام بلغة البرمجة Kotlin.

2. احصل على نموذج التعليمات البرمجية

استنساخ المستودع

انسخ مستودع GitHub من سطر الأوامر:

$ git clone https://github.com/firebase/codelab-friendlychat-android

استيراد إلى Android Studio

في Android Studio، حدد File > Open ، ثم حدد دليل build-android-start ( android_studio_folder ) من الدليل الذي قمت بتنزيل نموذج التعليمات البرمجية فيه.

يجب أن يكون لديك الآن مشروع build-android-start مفتوحًا في Android Studio. إذا رأيت تحذيرًا بشأن فقدان ملف google-services.json ، فلا تقلق. سيتم إضافتها في خطوة لاحقة.

التحقق من التبعيات

في هذا الدرس التطبيقي حول التعليمات البرمجية، تمت إضافة جميع التبعيات التي ستحتاج إليها بالفعل، ولكن من المهم فهم كيفية إضافة Firebase SDK إلى تطبيقك:

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 Emulator Suite لمحاكاة Firebase Auth، وقاعدة بيانات Realtime، و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 لتوصيل واجهة سطر الأوامر (CLI) بحسابك في Google. سيؤدي هذا إلى فتح نافذة متصفح جديدة لإكمال عملية تسجيل الدخول. تأكد من اختيار نفس الحساب الذي استخدمته عند إنشاء مشروع Firebase الخاص بك سابقًا.

4. اتصل بمجموعة Firebase Emulator Suite

ابدأ المحاكيات

في جهازك الطرفي، قم بتشغيل الأمر التالي من جذر دليل 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 Emulator Suite:

واجهة مستخدم جناح المحاكي الرئيسية

اترك أمر emulators:start التشغيل لبقية البرنامج التدريبي للبرمجة.

قم بتوصيل التطبيق الخاص بك

في Android Studio، افتح 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 Emulator Suite.

انسخ الملف mock-google-services.json إلى المجلد build-android-start/app باسم google-services.json :

cp mock-google-services.json build-android-start/app/google-services.json

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

قم بتشغيل التطبيق

الآن بعد أن قمت باستيراد المشروع إلى Android Studio وإضافة ملف JSON لتكوين Firebase، أصبحت جاهزًا لتشغيل التطبيق لأول مرة.

  1. ابدأ تشغيل محاكي الأندرويد الخاص بك.
  2. في Android Studio، انقر فوق تشغيل ( ينفذ ) في شريط الأدوات.

يجب أن يتم تشغيل التطبيق على محاكي Android الخاص بك. في هذه المرحلة، يجب أن تشاهد قائمة رسائل فارغة، ولن يعمل إرسال واستقبال الرسائل. في الخطوة التالية من هذا الدرس التطبيقي حول التعليمات البرمجية، ستقوم بمصادقة المستخدمين حتى يتمكنوا من استخدام الدردشة الودية.

6. تمكين المصادقة

سيستخدم هذا التطبيق قاعدة بيانات Firebase Realtime لتخزين جميع رسائل الدردشة. ولكن قبل أن نضيف البيانات، يجب علينا التأكد من أن التطبيق آمن وأن المستخدمين المصادق عليهم فقط هم من يمكنهم نشر الرسائل. في هذه الخطوة، سنقوم بتمكين مصادقة 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 :

تسجيل الدخولالنشاط.kt

// Firebase instance variables
private lateinit var auth: FirebaseAuth

بعد ذلك، قم بتحرير طريقة onCreate() لتهيئة Firebase بنفس الطريقة التي قمت بها في MainActivity :

تسجيل الدخولالنشاط.kt

// Initialize FirebaseAuth
auth = Firebase.auth

أضف حقل ActivityResultLauncher إلى SignInActivity :

تسجيل الدخولالنشاط.kt

// ADD THIS
private val signIn: ActivityResultLauncher<Intent> =
        registerForActivityResult(FirebaseAuthUIActivityResultContract(), this::onSignInResult)

override fun onCreate(savedInstanceState: Bundle?) {
    // ...
}

بعد ذلك، قم بتحرير طريقة onStart() لبدء تدفق تسجيل الدخول إلى FirebaseUI:

تسجيل الدخولالنشاط.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 :

تسجيل الدخولالنشاط.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 من خلال عدد قليل من استدعاءات الطريقة ودون الحاجة إلى إدارة أي تكوين من جانب الخادم.

اختبر عملك

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

بعد تسجيل الدخول، افتح واجهة مستخدم Firebase Emulator Suite في متصفحك، ثم انقر فوق علامة التبويب "المصادقة" لرؤية حساب المستخدم الذي تم تسجيل دخوله لأول مرة.

7. قراءة الرسائل

في هذه الخطوة، سنضيف وظيفة لقراءة وعرض الرسائل المخزنة في قاعدة بيانات Realtime.

استيراد رسائل عينة

  1. في واجهة مستخدم Firebase Emulator Suite، حدد علامة التبويب Realtime Database .
  2. قم بسحب وإسقاط الملف initial_messages.json من نسختك المحلية من مستودع Codelab في عارض البيانات.

يجب أن يكون لديك الآن بعض الرسائل ضمن عقدة messages في قاعدة البيانات.

إقرأ البيانات

مزامنة الرسائل

نضيف في هذا القسم تعليمات برمجية تعمل على مزامنة الرسائل المضافة حديثًا إلى واجهة مستخدم التطبيق من خلال:

  • تهيئة قاعدة بيانات Firebase Realtime وإضافة مستمع للتعامل مع التغييرات التي تم إجراؤها على البيانات.
  • تحديث محول 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 باستخدام الكود المحدد أدناه. يضيف هذا الرمز جميع الرسائل الموجودة من قاعدة بيانات Realtime ثم يستمع إلى الإدخالات الفرعية الجديدة ضمن مسار messages في قاعدة بيانات Firebase Realtime. يضيف عنصرًا جديدًا إلى واجهة المستخدم لكل رسالة:

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 Realtime Database. قم بتحديث أساليب onPause() و onResume() في MainActivity كما هو موضح أدناه:

MainActivity.kt

public override fun onPause() {
    adapter.stopListening()
    super.onPause()
}

public override fun onResume() {
    super.onResume()
    adapter.startListening()
}

اختبار مزامنة الرسائل

  1. انقر فوق تشغيل ( ينفذ ).
  2. في واجهة مستخدم 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("")
}

تنفيذ إرسال الرسائل المصورة

في هذا القسم، ستضيف قدرة مستخدمي التطبيق على إرسال رسائل صور. يتم إنشاء رسالة مصورة باتباع الخطوات التالية:

  • اختر صورة
  • التعامل مع اختيار الصورة
  • كتابة رسالة صورة مؤقتة إلى قاعدة بيانات الوقت الحقيقي
  • البدء في تحميل الصورة المحددة
  • قم بتحديث عنوان URL لرسالة الصورة إلى عنوان الصورة التي تم تحميلها، بمجرد اكتمال التحميل

اختر صورة

لإضافة صور، يستخدم هذا الدرس التطبيقي حول الترميز Cloud Storage for Firebase. يعد التخزين السحابي مكانًا جيدًا لتخزين البيانات الثنائية لتطبيقك.

التعامل مع اختيار الصورة وكتابة رسالة مؤقتة

بمجرد قيام المستخدم بتحديد صورة، يتم تشغيل 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
            )
        }
}

اختبار إرسال الرسائل

  1. في Android Studio، انقر فوق ينفذ زر التشغيل .
  2. في محاكي Android الخاص بك، أدخل رسالة، ثم اضغط على زر الإرسال. يجب أن تكون الرسالة الجديدة مرئية في واجهة مستخدم التطبيق وفي واجهة مستخدم Firebase Emulator Suite.
  3. في محاكي Android، اضغط على الصورة "+" لتحديد صورة من جهازك. يجب أن تكون الرسالة الجديدة مرئية أولاً مع صورة عنصر نائب، ثم مع الصورة المحددة بمجرد اكتمال تحميل الصورة. يجب أن تكون الرسالة الجديدة مرئية أيضًا في Emulator Suite UI، وتحديدًا ككائن في علامة التبويب Realtime Database وككائن ثنائي كبير الحجم في علامة التبويب Storage.

9. تهانينا!

لقد قمت للتو بإنشاء تطبيق دردشة في الوقت الفعلي باستخدام Firebase!

ما تعلمته

  • مصادقة Firebase
  • قاعدة بيانات Firebase في الوقت الحقيقي
  • التخزين السحابي لـ Firebase

بعد ذلك، حاول استخدام ما تعلمته في هذا الدرس التطبيقي حول البرمجة لإضافة Firebase إلى تطبيق Android الخاص بك! للتعرف على المزيد حول Firebase، تفضل بزيارة firebase.google.com .

إذا كنت تريد معرفة كيفية إعداد مشروع Firebase حقيقي واستخدام موارد Firebase الحقيقية (بدلاً من المشروع التجريبي والموارد التي تمت محاكاتها فقط )، فتابع إلى الخطوة التالية.

ملاحظة: حتى بعد إعداد مشروع Firebase حقيقي، وخاصة عندما تبدأ في إنشاء تطبيق حقيقي، نوصي باستخدام Firebase Local Emulator Suite للتطوير والاختبار.

10. اختياري: إنشاء مشروع Firebase وإعداده

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

إنشاء مشروع Firebase

  1. في متصفحك، انتقل إلى وحدة تحكم Firebase .
  2. حدد إضافة مشروع .
  3. حدد أو أدخل اسم المشروع. يمكنك استخدام أي اسم تريده.
  4. لا تحتاج إلى Google Analytics لإجراء الدرس التطبيقي حول التعليمات البرمجية، لذا يمكنك تخطي تمكينه لمشروعك.
  5. انقر فوق إنشاء مشروع . عندما يصبح مشروعك جاهزًا، انقر فوق "متابعة" .

أضف 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 الخاص بك:

  1. من شاشة النظرة العامة لمشروعك الجديد، انقر فوق أيقونة Android لبدء سير عمل الإعداد: إضافة تطبيق أندرويد
  2. في الشاشة التالية، أدخل com.google.firebase.codelab.friendlychat كاسم الحزمة لتطبيقك.
  3. انقر على "تسجيل التطبيق" ، ثم انقر على "تنزيل google-services.json" لتنزيل ملف تكوين Firebase.
  4. انسخ ملف google-services.json إلى دليل app لمشروع Android الخاص بك.
  5. تخطي الخطوات التالية الموضحة في سير عمل إعداد وحدة التحكم (تم تنفيذها بالفعل من أجلك في مشروع build-android-start ).
  6. تأكد من أن جميع التبعيات متاحة لتطبيقك عن طريق مزامنة مشروعك مع ملفات Gradle. من شريط أدوات Android Studio، حدد ملف > مزامنة المشروع مع ملفات Gradle . قد تحتاج أيضًا إلى تشغيل Build/Clean Project و Build/Rebuild Project لإجراء تغييرات التكوين.

تكوين مصادقة Firebase

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

  1. في وحدة تحكم Firebase ، حدد المصادقة من لوحة التنقل الموجودة على الجانب الأيسر.
  2. حدد علامة التبويب طريقة تسجيل الدخول .
  3. انقر فوق البريد الإلكتروني/كلمة المرور ، ثم قم بتبديل المفتاح إلى وضع التمكين (اللون الأزرق).
  4. انقر فوق Google ، ثم قم بتبديل المفتاح إلى وضع التمكين (الأزرق) وقم بتعيين بريد إلكتروني لدعم المشروع.

إذا ظهرت لك أخطاء لاحقًا في هذا الدرس التطبيقي حول الترميز مع الرسالة "CONFIGURATION_NOT_FOUND"، فارجع إلى هذه الخطوة وتحقق جيدًا من عملك.

تكوين قاعدة البيانات في الوقت الحقيقي

يقوم التطبيق الموجود في هذا الدرس التطبيقي حول الترميز بتخزين رسائل الدردشة في قاعدة بيانات Firebase Realtime. في هذا القسم، سنقوم بإنشاء قاعدة بيانات وتهيئة أمانها عبر لغة تكوين JSON تسمى قواعد أمان Firebase.

  1. في وحدة تحكم Firebase ، حدد Realtime Database من لوحة التنقل الموجودة على الجانب الأيسر.
  2. انقر فوق إنشاء قاعدة بيانات لإنشاء مثيل قاعدة بيانات Realtime جديد. عندما يُطلب منك ذلك، حدد منطقة us-central1 ، ثم انقر فوق "التالي" .
  3. عند مطالبتك بقواعد الأمان، اختر وضع القفل ، ثم انقر فوق تمكين .
  4. بمجرد إنشاء مثيل قاعدة البيانات، حدد علامة التبويب "القواعد" ، ثم قم بتحديث تكوين القواعد بما يلي:
     {
       "rules": {
         "messages": {
           ".read": "auth.uid != null",
           ".write": "auth.uid != null"
         }
       }
     }
    

لمزيد من المعلومات حول كيفية عمل قواعد الأمان (بما في ذلك الوثائق المتعلقة بالمتغير "auth")، راجع وثائق أمان قاعدة بيانات Realtime .

قم بتكوين التخزين السحابي لـ Firebase

  1. في وحدة تحكم Firebase ، حدد التخزين من لوحة التنقل الموجودة على الجانب الأيسر.
  2. انقر فوق البدء لتمكين التخزين السحابي لمشروعك.
  3. اتبع الخطوات الموجودة في مربع الحوار لإعداد الحاوية الخاصة بك، باستخدام الإعدادات الافتراضية المقترحة.

الاتصال بموارد Firebase

في خطوة سابقة من هذا الدرس التطبيقي حول التعليمات البرمجية، قمت بإضافة ما يلي إلى MainActivity.kt . قامت هذه الكتلة الشرطية بتوصيل مشروع Android الخاص بك إلى Firebase Emulator Suite.

// 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 .