Firebase Android Codelab - สร้างการแชทที่เป็นมิตร

1. ภาพรวม

ภาพหน้าจอ

รูปภาพ: แอปแชทที่เป็นมิตรต่อการทำงาน

ยินดีต้อนรับสู่ codelab แชทที่เป็นมิตร ใน Codelab นี้ คุณจะได้เรียนรู้วิธีใช้แพลตฟอร์ม Firebase เพื่อสร้างแอปแชทบน Android

สิ่งที่คุณจะได้เรียนรู้

  • วิธีใช้ Firebase Authentication เพื่ออนุญาตให้ผู้ใช้ลงชื่อเข้าใช้
  • วิธีซิงค์ข้อมูลโดยใช้ Firebase Realtime Database
  • วิธีจัดเก็บไฟล์ไบนารีใน Cloud Storage สำหรับ Firebase
  • วิธีใช้ Firebase Local Emulator Suite เพื่อพัฒนาแอพ Android ด้วย Firebase

สิ่งที่คุณต้องการ

  • Android Studio เวอร์ชันล่าสุด
  • Android Emulator พร้อม 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 หายไป ไม่ต้องกังวล จะถูกเพิ่มในขั้นตอนต่อไป

ตรวจสอบการพึ่งพา

ใน Codelab นี้ การอ้างอิงทั้งหมดที่คุณต้องการได้ถูกเพิ่มให้กับคุณแล้ว แต่สิ่งสำคัญคือต้องเข้าใจวิธีเพิ่ม 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

ใน Codelab นี้ คุณจะใช้ Firebase Emulator Suite เพื่อจำลอง Firebase Auth, Realtime Database และ Cloud Storage ในเครื่อง สิ่งนี้มอบสภาพแวดล้อมการพัฒนาในท้องถิ่นที่ปลอดภัย รวดเร็ว และไม่มีค่าใช้จ่ายในการสร้างแอปของคุณ

ติดตั้ง Firebase CLI

ก่อนอื่นคุณจะต้องติดตั้ง 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 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 UI:

หน้าแรกของ Emulator Suite UI

ปล่อยให้ emulators:start ทำงานสำหรับส่วนที่เหลือของ codelab

เชื่อมต่อแอปของคุณ

ใน 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 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

ในขั้นตอนสุดท้ายของ Codelab นี้ คุณจะได้เรียนรู้วิธีสร้างโปรเจ็กต์ Firebase และแอป Firebase สำหรับ Android จริง เพื่อให้คุณสามารถแทนที่ไฟล์ JSON จำลองนี้ด้วยการกำหนดค่าของคุณเอง

เรียกใช้แอพ

เมื่อคุณนำเข้าโปรเจ็กต์ไปยัง Android Studio และเพิ่มไฟล์ JSON การกำหนดค่า Firebase แล้ว คุณก็พร้อมที่จะเรียกใช้แอปเป็นครั้งแรก

  1. เริ่ม Android Emulator ของคุณ
  2. ใน Android Studio คลิก เรียกใช้ ( ดำเนินการ ) ในแถบเครื่องมือ

แอปควรเปิดใช้งานบน Android Emulator ของคุณ ณ จุดนี้ คุณควรเห็นรายการข้อความที่ว่างเปล่า และการส่งและรับข้อความจะไม่ทำงาน ในขั้นตอนต่อไปของ Codelab นี้ คุณจะตรวจสอบผู้ใช้เพื่อให้สามารถใช้การแชทที่เป็นมิตรได้

6. เปิดใช้งานการรับรองความถูกต้อง

แอปนี้จะใช้ Firebase Realtime Database เพื่อจัดเก็บข้อความแชททั้งหมด ก่อนที่เราจะเพิ่มข้อมูล เราควรตรวจสอบให้แน่ใจว่าแอปนั้นปลอดภัยและมีเพียงผู้ใช้ที่ผ่านการรับรองความถูกต้องเท่านั้นที่สามารถโพสต์ข้อความได้ ในขั้นตอนนี้ เราจะเปิดใช้งาน Firebase Authentication และกำหนดค่า Realtime Database Security Rules

เพิ่มฟังก์ชันการลงชื่อเข้าใช้ขั้นพื้นฐาน

ต่อไปเราจะเพิ่มโค้ดการตรวจสอบสิทธิ์ 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 Emulator ของคุณ คุณควรถูกส่งไปที่หน้าจอลงชื่อเข้าใช้ทันที แตะปุ่ม ลงชื่อเข้าใช้ด้วยอีเมล จากนั้นสร้างบัญชี หากดำเนินการทุกอย่างถูกต้องคุณควรจะถูกส่งไปยังหน้าจอข้อความ

หลังจากลงชื่อเข้าใช้ ให้เปิด Firebase Emulator Suite UI ในเบราว์เซอร์ จากนั้นคลิกแท็บ การรับรองความถูกต้อง เพื่อดูบัญชีผู้ใช้ที่ลงชื่อเข้าใช้ครั้งแรก

7. อ่านข้อความ

ในขั้นตอนนี้ เราจะเพิ่มฟังก์ชันในการอ่านและแสดงข้อความที่จัดเก็บไว้ใน Realtime Database

นำเข้าข้อความตัวอย่าง

  1. ใน Firebase Emulator Suite UI เลือกแท็บ ฐานข้อมูลเรียลไทม์
  2. ลากและวางไฟล์ initial_messages.json จากสำเนาที่เก็บ codelab ในเครื่องของคุณลงในโปรแกรมดูข้อมูล

ตอนนี้คุณควรมีข้อความสองสามข้อความภายใต้โหนด messages ของฐานข้อมูล

อ่านข้อมูล

ซิงโครไนซ์ข้อความ

ในส่วนนี้ เราเพิ่มโค้ดที่ซิงโครไนซ์ข้อความที่เพิ่มใหม่ไปยัง UI ของแอปโดย:

  • การเริ่มต้นฐานข้อมูลเรียลไทม์ของ 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 เพิ่มองค์ประกอบใหม่ให้กับ UI สำหรับแต่ละข้อความ:

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 UI ให้กลับไปที่แท็บ ฐานข้อมูลเรียลไทม์ จากนั้นเพิ่มข้อความใหม่ด้วยตนเอง ยืนยันว่าข้อความปรากฏในแอป Android ของคุณ:

ขอแสดงความยินดี คุณเพิ่งเพิ่มฐานข้อมูลเรียลไทม์ไปยังแอปของคุณ!

8. ส่งข้อความ

ใช้การส่งข้อความ

ในส่วนนี้ คุณจะเพิ่มความสามารถสำหรับผู้ใช้แอปในการส่งข้อความ ข้อมูลโค้ดด้านล่างจะรับฟังเหตุการณ์การคลิกบนปุ่มส่ง สร้างวัตถุ FriendlyMessage ใหม่ที่มีเนื้อหาของฟิลด์ข้อความ และพุชข้อความไปยังฐานข้อมูล วิธีการ push() เพิ่ม ID ที่สร้างขึ้นโดยอัตโนมัติไปยังเส้นทางของวัตถุที่ถูกผลัก รหัสเหล่านี้เป็นรหัสตามลำดับซึ่งทำให้มั่นใจได้ว่าข้อความใหม่จะถูกเพิ่มที่ส่วนท้ายของรายการ

อัปเดตการคลิกฟังของปุ่มส่งในเมธอด 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 ของข้อความรูปภาพเป็นของรูปภาพที่อัปโหลด เมื่ออัปโหลดเสร็จแล้ว

เลือกรูปภาพ

ในการเพิ่มรูปภาพ Codelab นี้ใช้ Cloud Storage สำหรับ 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
            )
        }
}

ทดสอบการส่งข้อความ

  1. ใน Android Studio ให้คลิก ดำเนินการ ปุ่ม เรียกใช้
  2. ใน Android Emulator ให้ป้อนข้อความ จากนั้นแตะปุ่มส่ง ข้อความใหม่ควรจะมองเห็นได้ใน UI ของแอปและใน Firebase Emulator Suite UI
  3. ใน Android Emulator ให้แตะรูปภาพ "+" เพื่อเลือกรูปภาพจากอุปกรณ์ของคุณ ข้อความใหม่ควรมองเห็นได้ก่อนด้วยรูปภาพตัวยึด จากนั้นตามด้วยรูปภาพที่เลือกเมื่อการอัปโหลดรูปภาพเสร็จสมบูรณ์ ข้อความใหม่ควรจะมองเห็นได้ใน Emulator Suite UI โดยเฉพาะเมื่อเป็นวัตถุในแท็บฐานข้อมูลเรียลไทม์และหยดในแท็บพื้นที่เก็บข้อมูล

9. ยินดีด้วย!

คุณเพิ่งสร้างแอปพลิเคชันแชทแบบเรียลไทม์โดยใช้ Firebase!

สิ่งที่คุณได้เรียนรู้

  • การรับรองความถูกต้องของ Firebase
  • ฐานข้อมูลเรียลไทม์ของ Firebase
  • ที่เก็บข้อมูลบนคลาวด์สำหรับ Firebase

ต่อไป ลองใช้สิ่งที่คุณได้เรียนรู้ใน Codelab นี้เพื่อเพิ่ม Firebase ลงในแอป Android ของคุณเอง! หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ Firebase โปรดไปที่ firebase.google.com

หากต้องการเรียนรู้วิธีตั้งค่าโปรเจ็กต์ Firebase จริง และใช้ทรัพยากร Firebase จริง (แทนโปรเจ็กต์สาธิตและทรัพยากรจำลอง เท่านั้น ) ให้ดำเนินการต่อในขั้นตอนถัดไป

หมายเหตุ: แม้หลังจากที่คุณตั้งค่าโปรเจ็กต์ Firebase จริงแล้ว และ โดยเฉพาะอย่างยิ่ง เมื่อคุณเริ่มต้นสร้างแอปจริง เราขอแนะนำให้ใช้ Firebase Local Emulator Suite สำหรับการพัฒนาและการทดสอบ

10. ทางเลือก: สร้างและตั้งค่าโครงการ Firebase

ในขั้นตอนนี้ คุณจะสร้างโครงการ Firebase จริงและแอป Firebase สำหรับ Android เพื่อใช้กับ Codelab นี้ คุณจะเพิ่มการกำหนดค่า Firebase เฉพาะแอปลงในแอปด้วย และสุดท้าย คุณจะต้องตั้งค่าทรัพยากร Firebase จริงเพื่อใช้กับแอปของคุณ

สร้างโครงการ Firebase

  1. ในเบราว์เซอร์ ให้ไปที่ คอนโซล Firebase
  2. เลือก เพิ่มโครงการ
  3. เลือกหรือป้อนชื่อโครงการ คุณสามารถใช้ชื่อใดก็ได้ที่คุณต้องการ
  4. คุณไม่จำเป็นต้องใช้ Google Analytics สำหรับ Codelab นี้ คุณจึงสามารถข้ามการเปิดใช้งานสำหรับโครงการของคุณได้
  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 เพื่อเปิดเวิร์กโฟลว์การตั้งค่า: เพิ่มแอพ 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 เลือก File > Sync Project with Gradle Files คุณอาจต้องเรียกใช้ Build/Clean Project และ Build/Rebuild Project เพื่อให้การเปลี่ยนแปลงการกำหนดค่าเกิดขึ้น

กำหนดค่าการรับรองความถูกต้องของ Firebase

ก่อนที่แอปของคุณจะเข้าถึง Firebase Authentication API ในนามของผู้ใช้ คุณต้องเปิดใช้ Firebase Authentication และผู้ให้บริการลงชื่อเข้าใช้ที่คุณต้องการใช้ในแอป

  1. ใน คอนโซล Firebase เลือก การรับรองความถูกต้อง จากแผงนำทางด้านซ้าย
  2. เลือกแท็บ วิธีการลงชื่อเข้า ใช้
  3. คลิก อีเมล/รหัสผ่าน จากนั้นสลับสวิตช์เป็นเปิดใช้งาน (สีน้ำเงิน)
  4. คลิก Google จากนั้นสลับสวิตช์เป็นเปิดใช้งาน (สีน้ำเงิน) และตั้งค่าอีเมลสนับสนุนโครงการ

หากคุณพบข้อผิดพลาดในภายหลังใน Codelab นี้พร้อมข้อความ "CONFIGURATION_NOT_FOUND" ให้กลับมาที่ขั้นตอนนี้และตรวจสอบงานของคุณอีกครั้ง

กำหนดค่าฐานข้อมูลเรียลไทม์

แอปใน Codelab นี้เก็บข้อความแชทไว้ใน Firebase Realtime Database ในส่วนนี้ เราจะสร้างฐานข้อมูลและกำหนดค่าความปลอดภัยผ่านภาษาการกำหนดค่า JSON ที่เรียกว่ากฎความปลอดภัยของ Firebase

  1. ใน คอนโซล Firebase เลือก ฐานข้อมูลเรียลไทม์ จากแผงนำทางด้านซ้าย
  2. คลิก สร้างฐานข้อมูล เพื่อสร้างอินสแตนซ์ฐานข้อมูลเรียลไทม์ใหม่ เมื่อได้รับแจ้ง ให้เลือกภูมิภาค us-central1 จากนั้นคลิก ถัดไป
  3. เมื่อได้รับแจ้งเกี่ยวกับกฎความปลอดภัย ให้เลือก โหมดล็อก แล้วคลิก เปิดใช้
  4. เมื่อสร้างอินสแตนซ์ฐานข้อมูลแล้ว ให้เลือกแท็บ กฎ จากนั้นอัปเดตการกำหนดค่ากฎด้วยสิ่งต่อไปนี้:
     {
       "rules": {
         "messages": {
           ".read": "auth.uid != null",
           ".write": "auth.uid != null"
         }
       }
     }
    

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานของกฎความปลอดภัย (รวมถึงเอกสารเกี่ยวกับตัวแปร "auth") โปรดดู เอกสารประกอบด้านความปลอดภัยของฐานข้อมูลเรียลไทม์

กำหนดค่า Cloud Storage สำหรับ Firebase

  1. ใน คอนโซล Firebase เลือก ที่เก็บข้อมูล จากแผงนำทางด้านซ้าย
  2. คลิก เริ่มต้นใช้งาน เพื่อเปิดใช้งาน Cloud Storage สำหรับโครงการของคุณ
  3. ทำตามขั้นตอนในกล่องโต้ตอบเพื่อตั้งค่าบัคเก็ตของคุณ โดยใช้ค่าเริ่มต้นที่แนะนำ

เชื่อมต่อกับทรัพยากร Firebase

ในขั้นตอนก่อนหน้าของ Codelab นี้ คุณได้เพิ่มสิ่งต่อไปนี้ใน 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