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

1. ภาพรวม

ภาพหน้าจอ

รูปภาพ: แอพ Working Friendly Chat

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

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

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

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

  • Android Studio เวอร์ชัน 4.2+
  • Android Emulator พร้อม Android 5.0+
  • Java 7 หรือสูงกว่า ในการติดตั้ง 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

buildscript {
    // ...

    dependencies {
        classpath 'com.android.tools.build:gradle:4.1.2'

        // The google-services plugin is required to parse the google-services.json file
        classpath 'com.google.gms:google-services:4.3.5'
    }
}

app/build.gradle

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:19.0.0'

    // Firebase SDK
    implementation platform('com.google.firebase:firebase-bom:26.6.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:7.2.0'
    implementation 'com.firebaseui:firebase-ui-database:7.2.0'
}

3. ติดตั้ง Firebase CLI

ในการรัน Firebase Emulator Suite คุณต้องติดตั้งและใช้ Firebase CLI

ติดตั้ง CLI

ตัวเลือก 1 - ติดตั้งด้วย npm

หากคุณมี Node.js และ npm ติดตั้งอยู่บนเครื่องของคุณแล้ว คุณสามารถติดตั้ง CLI ด้วยคำสั่งต่อไปนี้:

npm install -g firebase-tools@latest

ตัวเลือก 2 - ติดตั้งไบนารีแบบสแตนด์อโลน

หากคุณไม่มี Node.js/npm หรือคุณยังใหม่ต่อการพัฒนาแอป คุณสามารถติดตั้ง CLI เป็นไบนารีแบบสแตนด์อโลนได้โดยทำตาม คำแนะนำสำหรับแพลตฟอร์มของคุณที่นี่

ตรวจสอบการติดตั้ง

เมื่อคุณติดตั้ง Firebase CLI แล้ว ให้รันคำสั่งต่อไปนี้เพื่อให้แน่ใจว่าคุณมีเวอร์ชัน 9.11.0 ขึ้นไป:

firebase --version

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 ของคุณ
  2. ใน Android Studio คลิก เรียกใช้ ( ดำเนินการ ) ในแถบเครื่องมือ

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

6. เปิดใช้งานการตรวจสอบสิทธิ์

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

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

ต่อไป เราจะเพิ่มรหัสการตรวจสอบสิทธิ์พื้นฐานของ Firebase ลงในแอปเพื่อตรวจหาผู้ใช้และใช้งานหน้าจอลงชื่อเข้าใช้

ตรวจสอบผู้ใช้ปัจจุบัน

ขั้นแรกให้เพิ่มตัวแปรอินสแตนซ์ต่อไปนี้ในคลาส MainActivity.kt :

MainActivity.kt

// Firebase instance variables
private lateinit var auth: FirebaseAuth

ตอนนี้ มาแก้ไข MainActivity เพื่อส่งผู้ใช้ไปยังหน้าจอลงชื่อเข้าใช้เมื่อใดก็ตามที่พวกเขาเปิดแอปและไม่ผ่านการตรวจสอบสิทธิ์ เพิ่มสิ่งต่อไปนี้ใน onCreate() หลังจาก แนบการ binding เข้ากับมุมมอง:

MainActivity.kt

// Initialize Firebase Auth and check if the user is signed in
auth = Firebase.auth
if (auth.currentUser == null) {
    // Not signed in, launch the Sign In activity
    startActivity(Intent(this, SignInActivity::class.java))
    finish()
    return
}

นอกจากนี้เรายังต้องการตรวจสอบว่าผู้ใช้ลงชื่อเข้าใช้ระหว่าง onStart() :

MainActivity.kt

public override fun onStart() {
    super.onStart()
    // Check if user is signed in.
    if (auth.currentUser == null) {
        // Not signed in, launch the Sign In activity
        startActivity(Intent(this, SignInActivity::class.java))
        finish()
        return
    }
}

จากนั้นใช้ getUserPhotoUrl() และ getUserName() เพื่อส่งคืนข้อมูลที่เหมาะสมเกี่ยวกับผู้ใช้ Firebase ที่รับรองความถูกต้องในปัจจุบัน:

MainActivity.kt

private fun getPhotoUrl(): String? {
    val user = auth.currentUser
    return user?.photoUrl?.toString()
}

private fun getUserName(): String? {
    val user = auth.currentUser
    return if (user != null) {
        user.displayName
    } else ANONYMOUS
}

จากนั้นใช้วิธี signOut() เพื่อจัดการกับปุ่มออกจากระบบ:

MainActivity.kt

private fun signOut() {
    AuthUI.getInstance().signOut()
    startActivity(Intent(this, SignInActivity::class.java))
    finish()
}

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

ใช้หน้าจอลงชื่อเข้าใช้

เปิดไฟล์ SignInActivity.kt ที่นี่ใช้ปุ่มลงชื่อเข้าใช้แบบง่ายเพื่อเริ่มต้นการตรวจสอบสิทธิ์ ในส่วนนี้ คุณจะใช้ FirebaseUI เพื่อใช้ตรรกะในการลงชื่อเข้าใช้

เพิ่มตัวแปรอินสแตนซ์ Auth ในคลาส SignInActivity ภายใต้ความคิดเห็น // Firebase instance variables :

SignInActivity.kt

// Firebase instance variables
private lateinit var auth: FirebaseAuth

จากนั้น แก้ไข onCreate() เพื่อเริ่มต้น Firebase ในลักษณะเดียวกับที่คุณทำใน MainActivity :

SignInActivity.kt

// Initialize FirebaseAuth
auth = Firebase.auth

เพิ่มฟิลด์ ActivityResultLauncher ไปยัง SignInActivity :

SignInActivity.kt

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

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

ถัดไป แก้ไข onStart() เพื่อเริ่มขั้นตอนการลงชื่อเข้าใช้ FirebaseUI:

SignInActivity.kt

public override fun onStart() {
    super.onStart()

    // If there is no signed in user, launch FirebaseUI
    // Otherwise head to MainActivity
    if (Firebase.auth.currentUser == null) {
        // Sign in with FirebaseUI, see docs for more details:
        // https://firebase.google.com/docs/auth/android/firebaseui
        val signInIntent = AuthUI.getInstance()
                .createSignInIntentBuilder()
                .setLogo(R.mipmap.ic_launcher)
                .setAvailableProviders(listOf(
                        AuthUI.IdpConfig.EmailBuilder().build(),
                        AuthUI.IdpConfig.GoogleBuilder().build(),
                ))
                .build()

        signIn.launch(signInIntent)
    } else {
        goToMainActivity()
    }
}

ถัดไป ใช้เมธอด onSignInResult เพื่อจัดการผลการลงชื่อเข้าใช้ หากผลการลงชื่อเข้าใช้สำเร็จ ให้ไปที่ MainActivity :

SignInActivity.kt

private fun onSignInResult(result: FirebaseAuthUIAuthenticationResult) {
    if (result.resultCode == RESULT_OK) {
        Log.d(TAG, "Sign in successful!")
        goToMainActivity()
    } else {
        Toast.makeText(
                this,
                "There was an error signing in",
                Toast.LENGTH_LONG).show()

        val response = result.idpResponse
        if (response == null) {
            Log.w(TAG, "Sign in canceled")
        } else {
            Log.w(TAG, "Sign in error", response.error)
        }
    }
}

แค่นั้นแหละ! คุณได้ใช้การรับรองความถูกต้องด้วย FirebaseUI ในการเรียกใช้เมธอดเพียงไม่กี่เมธอด และไม่จำเป็นต้องจัดการการกำหนดค่าฝั่งเซิร์ฟเวอร์ใดๆ

ทดสอบการทำงานของคุณ

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

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

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

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

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

  1. ใน Firebase Emulator Suite UI ให้เลือกแท็บ Realtime Database
  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 อัปเดต onPause() และ onResume() ใน MainActivity ดังที่แสดงด้านล่าง:

MainActivity.kt

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

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

ทดสอบการซิงค์ข้อความ

  1. คลิก เรียกใช้ ( ดำเนินการ ).
  2. ใน UI ของ Emulator Suite ให้กลับไปที่แท็บ Realtime Database แล้วเพิ่มข้อความใหม่ด้วยตนเอง ยืนยันว่าข้อความแสดงขึ้นในแอป 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 ข้อความรูปภาพเป็น URL ของรูปภาพที่อัปโหลด เมื่ออัปโหลดเสร็จสิ้น

เลือกรูปภาพ

ในการเพิ่มรูปภาพ Codelab นี้ใช้ Cloud Storage สำหรับ Firebase Cloud Storage เป็นที่ที่ดีในการจัดเก็บข้อมูลไบนารีของแอปของคุณ

จัดการการเลือกรูปภาพและเขียนข้อความชั่วคราว

เมื่อผู้ใช้เลือกรูปภาพแล้ว ความ Intent ในการเลือกรูปภาพจะเริ่มต้นขึ้น มีการใช้งานแล้วในโค้ดที่ส่วนท้ายของ onCreate() เมื่อเสร็จแล้วจะเรียก MainActivity 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 ให้แตะรูปภาพ "+" เพื่อเลือกรูปภาพจากอุปกรณ์ของคุณ ข้อความใหม่ควรปรากฏให้เห็นก่อนด้วยภาพตัวแทน จากนั้นจึงแสดงด้วยภาพที่เลือกเมื่อการอัปโหลดภาพเสร็จสิ้น ข้อความใหม่ควรมองเห็นได้ใน UI ของ Emulator Suite โดยเฉพาะในฐานะออบเจ็กต์ในแท็บฐานข้อมูลเรียลไทม์และแบบหยดในแท็บพื้นที่เก็บข้อมูล

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. คลิก Register App จากนั้นคลิก Download 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 และผู้ให้บริการลงชื่อเข้าใช้ที่คุณต้องการใช้ในแอป

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

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

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

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

  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