Firebase Android Codelab – פיתוח Friendly Chat

1. סקירה כללית

צילום מסך

תמונה: אפליקציית צ'אט ידידותית לעבודה.

טוב שהגעת ל-Face Chat Codelab. בקודלאב הזה תלמדו איך להשתמש בפלטפורמת Firebase כדי ליצור אפליקציית צ'אט ל-Android.

מה תלמדו

  • איך משתמשים באימות ב-Firebase כדי לאפשר למשתמשים להיכנס לחשבון.
  • איך מסנכרנים נתונים באמצעות מסד נתונים בזמן אמת ב-Firebase.
  • איך מאחסנים קבצים בינאריים ב-Cloud Storage for Firebase.
  • איך משתמשים בחבילת האמולטור המקומי של Firebase כדי לפתח אפליקציה ל-Android עם Firebase.

מה צריך

  • הגרסה האחרונה של Android Studio.
  • אמולטור Android עם Android מגרסה 5.0 ואילך.
  • Node.js בגרסה 10 ואילך (כדי להשתמש ב-Emulator Suite).
  • Java 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. התקנת ה-CLI של Firebase

בקודלאב הזה נעשה שימוש ב-Firebase Emulator Suite כדי לדמות באופן מקומי את Firebase Auth, את Realtime Database ואת Cloud Storage. כך תוכלו ליצור סביבה מקומית לפיתוח מהירה, בטוחה וללא עלות, שבה תוכלו לפתח את האפליקציה.

התקנת ה-CLI של Firebase

בשלב הראשון צריך להתקין את Firebase CLI. אם אתם משתמשים ב-macOS או ב-Linux, אתם יכולים להריץ את פקודת ה-cURL הבאה:

curl -sL https://firebase.tools | bash

אם משתמשים ב-Windows, יש לקרוא את הוראות ההתקנה כדי לקבל קובץ בינארי נפרד או להתקין אותו דרך npm.

אחרי שתתקינו את ה-CLI, הפעלת firebase --version אמורה לדווח על גרסה 9.0.0 ואילך:

$ firebase --version
9.0.0

כניסה

מריצים את הפקודה firebase login כדי לחבר את ה-CLI לחשבון Google. ייפתח חלון חדש בדפדפן כדי להשלים את תהליך ההתחברות. חשוב לבחור באותו חשבון שבו השתמשתם כשיצרתם את פרויקט Firebase קודם.

4. חיבור לחבילת האמולטור של Firebase

הפעלת הסימולטורים

בטרמינל, מריצים את הפקודה הבאה מהרמה הבסיסית (root) של ספריית 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. למטרות של ה-Codelab הזה, סיפקנו קובץ 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

בשלב האחרון של ה-Codelab הזה תלמדו איך ליצור פרויקט Firebase אמיתי ואפליקציית Firebase ל-Android, כדי שתוכלו להחליף את קובץ ה-JSON המדומה הזה בתצורה משלכם.

הפעלת האפליקציה

עכשיו, אחרי שייבאתם את הפרויקט אל Android Studio והוספתם קובץ JSON של תצורת Firebase, אתם מוכנים להפעיל את האפליקציה בפעם הראשונה.

  1. מפעילים את האמולטור של Android.
  2. ב-Android Studio, לוחצים על הפעלה ( לבצע) בסרגל הכלים.

האפליקציה אמורה להיפתח באמולטור Android. בשלב זה אמורה להופיע רשימת הודעות ריקה, ושליחה וקבלה של הודעות לא תפעל. בשלב הבא של סדנת הקוד הזו, תבצעו אימות של משתמשים כדי שיוכלו להשתמש ב-Friendly Chat.

6. הפעלת האימות

האפליקציה תשתמש במסד הנתונים בזמן אמת ב-Firebase כדי לאחסן את כל הודעות הצ'אט. עם זאת, לפני שמוסיפים נתונים, צריך לוודא שהאפליקציה מאובטחת ושרק משתמשים מאומתים יכולים לפרסם הודעות. בשלב הזה נפעיל אימות ב-Firebase ונגדיר כללי אבטחה של מסדי נתונים בזמן אמת.

הוספת פונקציונליות בסיסית של כניסה לחשבון

בשלב הבא נוסיף לאפליקציה קוד אימות בסיסי ב-Firebase כדי לזהות משתמשים ולהטמיע מסך כניסה.

בדיקה של המשתמש הנוכחי

קודם מוסיפים את משתנה המכונה הבא לכיתה MainActivity.kt:

MainActivity.kt

// Firebase instance variables
private lateinit var auth: FirebaseAuth

עכשיו נשנה את MainActivity כדי לשלוח את המשתמש למסך הכניסה בכל פעם שהוא פותח את האפליקציה והאימות שלו לא בוצע. מוסיפים את הקוד הבא ל-method‏ 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() כדי להתחיל את תהליך הכניסה בממשק המשתמש של Firebase:

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 Emulator Suite בדפדפן ולוחצים על הכרטיסייה Authentication (אימות) כדי לראות את חשבון המשתמש הראשון שנכנס.

7. קריאת ההודעות

בשלב הזה נוסיף פונקציונליות לקריאה ולהצגה של הודעות המאוחסנות במסד נתונים בזמן אמת.

ייבוא הודעות לדוגמה

  1. בממשק המשתמש של Firebase Emulator Suite, בוחרים בכרטיסייה Realtime Database.
  2. גוררים ומשחררים את הקובץ 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 באמצעות הקוד שמוגדר בהמשך. הקוד הזה מוסיף את כל ההודעות הקיימות מ-Realtime Database, ולאחר מכן מקשיב להוספת רשומות צאצא חדשות בנתיב 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, מטמיעים את ה-method 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():

WonderMessageAdapter.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 time 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. Cloud Storage הוא מקום טוב לאחסון הנתונים הבינאריים של האפליקציה.

טיפול בבחירת תמונה וכתיבה של הודעה זמנית

אחרי שהמשתמש בוחר תמונה, האפשרות Intent לבחירת התמונה מופעלת. האפשרות הזו כבר מוטמעת בקוד בסוף ה-method onCreate(). בסיום, הוא קורא ל-method‏ 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, לוחצים על הלחצן לבצעRun.
  2. באמולטור Android, מזינים הודעה ומקישים על לחצן השליחה. ההודעה החדשה צריכה להופיע בממשק המשתמש של האפליקציה ובממשק המשתמש של Firebase Emulator Suite.
  3. באמולטור Android, מקישים על התמונה '+' כדי לבחור תמונה מהמכשיר. ההודעה החדשה אמורה להופיע קודם עם תמונה זמנית, ואז עם התמונה שנבחרה אחרי השלמת העלאת התמונה. ההודעה החדשה אמורה להופיע גם בממשק המשתמש של Emulator Suite, במיוחד כאובייקט בכרטיסייה Realtime Database וכ-blob בכרטיסייה Storage.

9. כל הכבוד!

פיתחתם אפליקציית צ'אט בזמן אמת באמצעות Firebase!

מה למדתם

  • אימות ב-Firebase
  • מסד נתונים בזמן אמת ב-Firebase
  • Cloud Storage for Firebase

לאחר מכן, נסו להשתמש במה שלמדתם ב-codelab הזה כדי להוסיף את Firebase לאפליקציה שלכם ל-Android. מידע נוסף על Firebase זמין בכתובת firebase.google.com.

כדי ללמוד איך מגדירים פרויקט Firebase אמיתי ומשתמשים במשאבים אמיתיים ב-Firebase (במקום פרויקט הדגמה ומשאבים בלבד שעברו הדמיה), ממשיכים לשלב הבא.

הערה: גם אחרי שמגדירים פרויקט Firebase אמיתי, ובמיוחד כשמתחילים לפתח אפליקציה אמיתית, מומלץ להשתמש בכלים לאמולטור המקומי ב-Firebase לפיתוח ולבדיקה.

10. אופציונלי: יצירה והגדרה של פרויקט Firebase

בשלב הזה תיצורו פרויקט Firebase אמיתי ואפליקציית Firebase ל-Android לשימוש בקודלאב הזה. תוכלו גם להוסיף לאפליקציה את ההגדרות הספציפיות לאפליקציה שלכם ב-Firebase. ולבסוף, מגדירים משאבי Firebase אמיתיים לשימוש באפליקציה.

יצירת פרויקט Firebase

  1. בדפדפן, נכנסים אל מסוף Firebase.
  2. בוחרים באפשרות Add project (הוספת פרויקט).
  3. בוחרים או מזינים שם פרויקט. אפשר להשתמש בכל שם שרוצים.
  4. אתם לא צריכים את Google Analytics עבור ה-Codelab הזה, לכן אפשר לדלג על ההפעלה שלו בפרויקט.
  5. לוחצים על Create Project. כשהפרויקט מוכן, לוחצים על Continue.

שדרוג של תוכנית התמחור ב-Firebase

כדי להשתמש ב-Cloud Storage for Firebase, פרויקט Firebase צריך להיות בתוכנית התמחור 'תשלום לפי שימוש' (Blaze), כלומר הוא צריך להיות מקושר לחשבון לחיוב ב-Cloud.

כדי לשדרג את הפרויקט לתוכנית Blaze:

  1. במסוף Firebase, בוחרים באפשרות שדרוג התוכנית.
  2. בוחרים את התוכנית 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:

  1. במסך הסקירה הכללית של הפרויקט החדש, לוחצים על סמל Android כדי להפעיל את תהליך ההגדרה: הוספת אפליקציה ל-Android
  2. במסך הבא, מזינים com.google.firebase.codelab.friendlychat בתור שם החבילה של האפליקציה.
  3. לוחצים על Register App (רישום אפליקציה) ואז על Download google-services.json (הורדת קובץ 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

כדי שהאפליקציה תוכל לגשת לממשקי ה-API לאימות ב-Firebase בשם המשתמשים שלכם, אתם צריכים להפעיל אימות ב-Firebase ואת ספקי הכניסה שבהם אתם רוצים להשתמש באפליקציה.

  1. במסוף Firebase, בוחרים באפשרות אימות בחלונית הניווט שבצד ימין.
  2. בוחרים בכרטיסייה שיטת כניסה.
  3. לוחצים על אימייל/סיסמה ומעבירים את המתג למצב מופעל (כחול).
  4. לוחצים על Google, מחליפים את המצב של המתג למצב מופעל (כחול) ומגדירים אימייל לתמיכה בפרויקט.

אם תקבלו שגיאות בהמשך הקודלאב עם ההודעה &#39;CONFIGURATION_NOT_FOUND&#39;, חזרו לשלב הזה ובדקו שוב את העבודה.

הגדרת מסד נתונים בזמן אמת

באפליקציה שבקודלאב הזה, הודעות הצ&#39;אט מאוחסנות ב-Firebase Realtime Database. בקטע הזה ניצור מסד נתונים נגדיר את האבטחה שלו באמצעות שפת תצורת JSON שנקראת 'כללי אבטחה של Firebase'.

  1. בחלונית השמאלית של מסוף Firebase, מרחיבים את Build ובוחרים באפשרות בזמן אמת Database.
  2. לוחצים על Create dataset.
  3. בוחרים מיקום למסד הנתונים ולוחצים על הבא.
    אם מדובר באפליקציה אמיתית, כדאי לבחור מיקום שקרוב למשתמשים שלך.
  4. לוחצים על הפעלה במצב בדיקה. צריך לקרוא את כתב הוויתור לגבי כללי האבטחה.
    בשלבים הבאים ב-Codelab הזה, צריך להוסיף 'כללי אבטחה' כדי לאבטח את הנתונים שלך. לא תפיץ או תחשוף אפליקציה באופן ציבורי, בלי להוסיף כללי אבטחה למסד הנתונים שלכם.
  5. לוחצים על יצירה.
  6. אחרי שיוצרים את המופע של מסד הנתונים, בוחרים בכרטיסייה כללים ומעדכנים את הגדרת הכללים באופן הבא:
     {
       "rules": {
         "messages": {
           ".read": "auth.uid != null",
           ".write": "auth.uid != null"
         }
       }
     }
    

למידע נוסף על אופן הפעולה של כללי אבטחה (כולל תיעוד על המשתנה "auth"), ראו מסמכי אבטחה של מסד נתונים בזמן אמת.

הגדרה של Cloud Storage for Firebase

  1. בחלונית הימנית של מסוף Firebase, מרחיבים את Build ובוחרים באפשרות Storage.
  2. לוחצים על תחילת העבודה.
  3. יש לבחור מיקום לקטגוריית האחסון המוגדרת כברירת מחדל.
    קטגוריות ב-US-WEST1, ב-US-CENTRAL1 וב-US-EAST1 יכולות לנצל את המסלול 'חינם תמיד' ל-Google Cloud Storage. לקטגוריות בכל שאר המיקומים יש תמחור ושימוש ב-Google Cloud Storage.
  4. לוחצים על התחלה במצב בדיקה. קוראים את כתב הוויתור לגבי כללי האבטחה.
    בהמשך הסדנה תוסיפו כללי אבטחה כדי לאבטח את הנתונים. לא תפיץ או תחשוף אפליקציה באופן ציבורי בלי להוסיף כללי אבטחה לקטגוריית האחסון שלכם.
  5. לוחצים על יצירה.

חיבור למשאבים של 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.