1. ภาพรวม
รูปภาพ: แอป Chat ที่เหมาะกับการทำงาน
ยินดีต้อนรับสู่ Codelab ของ Chat ที่เป็นมิตร ใน Codelab นี้ คุณจะได้เรียนรู้วิธีใช้แพลตฟอร์ม Firebase เพื่อสร้างแอปแชทบน Android
สิ่งที่คุณจะได้เรียนรู้
- วิธีใช้การตรวจสอบสิทธิ์ของ Firebase เพื่ออนุญาตให้ผู้ใช้ลงชื่อเข้าใช้
- วิธีซิงค์ข้อมูลโดยใช้ฐานข้อมูลเรียลไทม์ของ Firebase
- วิธีจัดเก็บไฟล์ไบนารีใน Cloud Storage for Firebase
- วิธีใช้ชุดโปรแกรมจำลองภายในของ Firebase เพื่อพัฒนาแอป Android ด้วย Firebase
สิ่งที่ต้องมี
- Android Studio เวอร์ชันล่าสุด
- โปรแกรมจำลอง Android ที่ใช้ Android 5.0 ขึ้นไป
- Node.js เวอร์ชัน 10 ขึ้นไป (เพื่อใช้ชุดโปรแกรมจำลอง)
- Java 8 ขึ้นไป หากต้องการติดตั้ง Java ให้ใช้วิธีการเหล่านี้ เพื่อตรวจสอบเวอร์ชัน ให้เรียกใช้
java -version
- มีความคุ้นเคยกับภาษาโปรแกรม Kotlin
2. รับโค้ดตัวอย่าง
โคลนที่เก็บ
โคลนที่เก็บ GitHub จากบรรทัดคำสั่งดังนี้
$ git clone https://github.com/firebase/codelab-friendlychat-android
นำเข้าไปยัง Android Studio
ใน Android Studio ให้เลือกไฟล์ > เปิด จากนั้นเลือกไดเรกทอรี build-android-start
( ) จากไดเรกทอรีที่คุณดาวน์โหลดโค้ดตัวอย่างมา
ตอนนี้คุณควรเปิดโปรเจ็กต์ build-android-start
ใน Android Studio แล้ว หากคุณเห็นคำเตือนเกี่ยวกับไฟล์ google-services.json
ที่ขาดหายไป ไม่ต้องกังวล โดยเราจะเพิ่มข้อมูลดังกล่าวในขั้นตอนถัดไป
ตรวจสอบทรัพยากร Dependency
ใน Codelab นี้ ระบบได้เพิ่มทรัพยากร Dependency ทั้งหมดให้คุณแล้ว แต่คุณต้องทำความเข้าใจวิธีเพิ่ม 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 เพื่อจำลองการตรวจสอบสิทธิ์ Firebase, 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
เริ่มโปรแกรมจำลอง
ในเทอร์มินัล ให้เรียกใช้คำสั่งต่อไปนี้จากรากของไดเรกทอรี 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 ในเว็บเบราว์เซอร์เพื่อดู UI ของ Firebase Emulator Suite ดังนี้
ให้คำสั่ง 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 แล้ว คุณก็พร้อมที่จะเรียกใช้แอปเป็นครั้งแรก
- เริ่มโปรแกรมจำลองของ Android
- ใน Android Studio ให้คลิกเรียกใช้ ( ) ในแถบเครื่องมือ
แอปจะเปิดขึ้นในโปรแกรมจำลองของ Android ในขั้นตอนนี้ คุณควรเห็นรายการข้อความว่างเปล่า และการส่งและรับข้อความจะไม่ทำงาน ในขั้นตอนถัดไปของ Codelab นี้ คุณจะต้องตรวจสอบสิทธิ์ผู้ใช้เพื่อให้ใช้ Chat ได้
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. อ่านข้อความ
ในขั้นตอนนี้ เราจะเพิ่มฟังก์ชันสำหรับอ่านและแสดงข้อความที่จัดเก็บไว้ใน Realtime Database
นำเข้าข้อความตัวอย่าง
- เลือกแท็บฐานข้อมูลเรียลไทม์ใน UI ชุดโปรแกรมจำลองของ Firebase
- ลากและวางไฟล์
initial_messages.json
จากสำเนาที่เก็บ Codelab ในเครื่องลงในเครื่องมือดูข้อมูล
ตอนนี้คุณควรมีข้อความ 2-3 ข้อความอยู่ใต้โหนด messages
ของฐานข้อมูล
อ่านข้อมูล
ซิงค์ข้อมูลข้อความ
ในส่วนนี้ เราจะเพิ่มโค้ดที่ใช้ซิงค์ข้อความที่เพิ่มใหม่ลงใน UI ของแอปโดยทำดังนี้
- การเริ่มต้นฐานข้อมูลเรียลไทม์ของ Firebase และเพิ่ม Listener เพื่อจัดการกับการเปลี่ยนแปลงที่ทำกับข้อมูล
- กำลังอัปเดตอะแดปเตอร์
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 โดยจะเพิ่มองค์ประกอบใหม่ลงใน 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()
}
ทดสอบการซิงค์ข้อความ
- คลิกเรียกใช้ ( )
- ใน UI ของชุดโปรแกรมจำลอง ให้กลับไปที่แท็บ Realtime Database แล้วเพิ่มข้อความใหม่ด้วยตนเอง ยืนยันว่าข้อความปรากฏในแอป Android โดยทำดังนี้
ยินดีด้วย คุณเพิ่งเพิ่มฐานข้อมูลแบบเรียลไทม์ลงในแอป
8. ส่งข้อความ
ใช้การส่งข้อความ
ในส่วนนี้ คุณจะเพิ่มความสามารถสำหรับผู้ใช้แอปที่จะส่งข้อความได้ ข้อมูลโค้ดด้านล่างจะเฝ้าติดตามเหตุการณ์การคลิกบนปุ่มส่ง สร้างออบเจ็กต์ FriendlyMessage
ใหม่ที่มีเนื้อหาของช่องข้อความ และพุชข้อความไปยังฐานข้อมูล เมธอด push()
จะเพิ่มรหัสที่สร้างขึ้นโดยอัตโนมัติไปยังเส้นทางของออบเจ็กต์ที่พุช รหัสเหล่านี้จะเรียงตามลำดับ ซึ่งช่วยให้มั่นใจได้ว่าข้อความใหม่จะถูกเพิ่มลงในท้ายรายการ
อัปเดต Listener การคลิกของปุ่มส่งในเมธอด onCreate()
ในชั้นเรียน MainActivity
โค้ดนี้อยู่ที่ด้านล่างของเมธอด onCreate()
แล้ว อัปเดตเนื้อหา onClick()
ให้ตรงกับโค้ดด้านล่าง
MainActivity.kt
// Disable the send button when there's no text in the input field
// See MyButtonObserver for details
binding.messageEditText.addTextChangedListener(MyButtonObserver(binding.sendButton))
// When the send button is clicked, send a text message
binding.sendButton.setOnClickListener {
val friendlyMessage = FriendlyMessage(
binding.messageEditText.text.toString(),
getUserName(),
getPhotoUrl(),
null /* no image */
)
db.reference.child(MESSAGES_CHILD).push().setValue(friendlyMessage)
binding.messageEditText.setText("")
}
ใช้การส่งข้อความรูปภาพ
ในส่วนนี้ คุณจะเพิ่มความสามารถสำหรับผู้ใช้แอปที่จะส่งข้อความรูปภาพได้ สร้างข้อความพร้อมรูปภาพได้ด้วยขั้นตอนต่อไปนี้
- เลือกรูปภาพ
- จัดการการเลือกรูปภาพ
- เขียนข้อความรูปภาพชั่วคราวไปยัง Realtime Database
- เริ่มอัปโหลดรูปภาพที่เลือก
- อัปเดต URL ข้อความรูปภาพเป็นของรูปภาพที่อัปโหลด เมื่ออัปโหลดเสร็จสมบูรณ์
เลือกรูปภาพ
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)
})
}
อัปโหลดรูปภาพและอัปเดตข้อความ
เพิ่ม Method putImageInStorage()
ใน MainActivity
ซึ่งถูกเรียกใช้ใน onImageSelected()
เพื่อเริ่มการอัปโหลดรูปภาพที่เลือก เมื่อการอัปโหลดเสร็จสมบูรณ์ คุณจะอัปเดตข้อความเพื่อใช้รูปภาพที่เหมาะสม
MainActivity.kt
private fun putImageInStorage(storageReference: StorageReference, uri: Uri, key: String?) {
// First upload the image to Cloud Storage
storageReference.putFile(uri)
.addOnSuccessListener(
this
) { taskSnapshot -> // After the image loads, get a public downloadUrl for the image
// and add it to the message.
taskSnapshot.metadata!!.reference!!.downloadUrl
.addOnSuccessListener { uri ->
val friendlyMessage =
FriendlyMessage(null, getUserName(), getPhotoUrl(), uri.toString())
db.reference
.child(MESSAGES_CHILD)
.child(key!!)
.setValue(friendlyMessage)
}
}
.addOnFailureListener(this) { e ->
Log.w(
TAG,
"Image upload task was unsuccessful.",
e
)
}
}
ทดสอบการส่งข้อความ
- ใน Android Studio ให้คลิกปุ่ม เรียกใช้
- ป้อนข้อความที่ต้องการแล้วแตะปุ่มส่งในโปรแกรมจำลอง Android ข้อความใหม่ควรแสดงใน UI ของแอปและใน UI ของ Firebase Emulator Suite
- ในโปรแกรมจำลองของ Android ให้แตะเครื่องหมาย "+" รูปภาพ เพื่อเลือกรูปภาพจากอุปกรณ์ ข้อความใหม่ควรแสดงพร้อมรูปภาพตัวยึดตำแหน่งก่อน ตามด้วยรูปภาพที่เลือกเมื่ออัปโหลดรูปภาพเสร็จสมบูรณ์แล้ว ข้อความใหม่ควรปรากฏใน UI ชุดโปรแกรมจำลองด้วย โดยเฉพาะอย่างยิ่งเป็นออบเจ็กต์ในแท็บ Realtime Database และเป็น BLOB ในแท็บพื้นที่เก็บข้อมูล
9. ยินดีด้วย
คุณเพิ่งสร้างแอปพลิเคชันแชทแบบเรียลไทม์โดยใช้ Firebase
สิ่งที่คุณได้เรียนรู้
- การตรวจสอบสิทธิ์ Firebase
- ฐานข้อมูลเรียลไทม์ของ Firebase
- Cloud Storage for Firebase
ต่อไป ให้ลองใช้สิ่งที่คุณได้เรียนรู้ใน Codelab นี้เพื่อเพิ่ม Firebase ไปยังแอป Android ของคุณเอง ดูข้อมูลเพิ่มเติมเกี่ยวกับ Firebase ได้ที่ firebase.google.com
หากต้องการดูวิธีตั้งค่าโปรเจ็กต์ Firebase จริง และใช้ทรัพยากร Firebase จริง (แทนโปรเจ็กต์สาธิตและเฉพาะทรัพยากรที่จำลอง) ให้ไปยังขั้นตอนถัดไป
หมายเหตุ: แม้คุณจะสร้างโครงการ Firebase จริงขึ้นมาแล้ว และโดยเฉพาะอย่างยิ่งเมื่อเริ่มสร้างแอปจริง เราขอแนะนำให้ใช้ Firebase Local Emulator Suite ในการพัฒนาและทดสอบ
10. ไม่บังคับ: สร้างและตั้งค่าโปรเจ็กต์ Firebase
ในขั้นตอนนี้ คุณจะได้สร้างโปรเจ็กต์ Firebase จริงและแอป Firebase บน Android เพื่อใช้กับ Codelab นี้ นอกจากนี้ คุณยังเพิ่มการกำหนดค่า Firebase เฉพาะแอปลงในแอปได้อีกด้วย และขั้นตอนสุดท้าย คุณจะต้องตั้งค่าทรัพยากร Firebase จริงเพื่อใช้กับแอป
สร้างโปรเจ็กต์ Firebase
- ไปที่คอนโซล Firebase ในเบราว์เซอร์
- เลือกเพิ่มโปรเจ็กต์
- เลือกหรือป้อนชื่อโปรเจ็กต์ คุณสามารถใช้ชื่อใดก็ได้ตามต้องการ
- คุณไม่จำเป็นต้องใช้ Google Analytics สำหรับ Codelab นี้ คุณจึงไม่ต้องเปิดใช้ Google Analytics สำหรับโปรเจ็กต์
- คลิกสร้างโปรเจ็กต์ เมื่อโปรเจ็กต์พร้อมแล้ว ให้คลิกต่อไป
เพิ่ม Firebase ลงในโปรเจ็กต์ Android
ก่อนเริ่มต้นขั้นตอนนี้ ให้รับแฮช SHA1 ของแอป เรียกใช้คำสั่งต่อไปนี้จากไดเรกทอรี build-android-start
ในเครื่องเพื่อระบุ SHA1 ของคีย์การแก้ไขข้อบกพร่อง
./gradlew signingReport Store: /Users/<username>/.android/debug.keystore Alias: AndroidDebugKey MD5: A5:88:41:04:8F:06:59:6A:AE:33:76:87:AA:AD:19:23 SHA1: A7:89:F5:06:A8:07:A1:22:EC:90:6A:A6:EA:C3:D4:8B:3A:30:AB:18 SHA-256: 05:A2:2A:35:EE:F2:51:23:72:4D:72:67:A5:6A:8A:58:22:2C:00:A6:AB:F6:45:D5:A1:82:D8:90:A4:69:C8:FE Valid until: Wednesday, August 10, 2044
คุณควรจะเห็นผลลัพธ์บางส่วนเหมือนกับด้านบน บรรทัดที่สำคัญคือแฮช SHA1
หากไม่พบแฮช SHA1 โปรดดูข้อมูลเพิ่มเติมในหน้านี้
กลับไปที่คอนโซล Firebase แล้วทำตามขั้นตอนต่อไปนี้เพื่อลงทะเบียนโปรเจ็กต์ Android กับโปรเจ็กต์ Firebase
- จากหน้าจอภาพรวมของโปรเจ็กต์ใหม่ ให้คลิกไอคอน Android เพื่อเปิดเวิร์กโฟลว์การตั้งค่า:
- ในหน้าจอถัดไป ให้ป้อน
com.google.firebase.codelab.friendlychat
เป็นชื่อแพ็กเกจของแอป - คลิกลงทะเบียนแอป แล้วคลิกดาวน์โหลด google-services.json เพื่อดาวน์โหลดไฟล์การกำหนดค่า Firebase
- คัดลอกไฟล์
google-services.json
ไปยังไดเรกทอรีapp
ของโปรเจ็กต์ Android - ข้ามขั้นตอนถัดไปที่แสดงในเวิร์กโฟลว์การตั้งค่าของคอนโซล (ดำเนินการให้คุณแล้วในโปรเจ็กต์
build-android-start
) - ตรวจสอบว่าทรัพยากร Dependency ทั้งหมดพร้อมใช้งานสำหรับแอปโดยการซิงค์โปรเจ็กต์กับไฟล์ Gradle จากแถบเครื่องมือของ Android Studio ให้เลือกไฟล์ > ซิงค์โปรเจ็กต์กับไฟล์ Gradle นอกจากนี้ คุณอาจต้องเรียกใช้สร้าง/ล้างโปรเจ็กต์และสร้าง/สร้างโครงการใหม่เพื่อให้การเปลี่ยนแปลงการกำหนดค่าเกิดขึ้น
กำหนดค่าการตรวจสอบสิทธิ์ Firebase
ก่อนที่แอปจะเข้าถึง API การตรวจสอบสิทธิ์ Firebase ในนามของผู้ใช้ได้ คุณต้องเปิดใช้การตรวจสอบสิทธิ์ Firebase และผู้ให้บริการการลงชื่อเข้าใช้ที่ต้องการใช้ในแอป
- ในคอนโซล Firebase ให้เลือกการตรวจสอบสิทธิ์จากแผงการนำทางด้านซ้าย
- เลือกแท็บวิธีการลงชื่อเข้าใช้
- คลิกอีเมล/รหัสผ่าน แล้วสลับสวิตช์เป็นเปิดใช้ (สีน้ำเงิน)
- คลิก Google จากนั้นสลับสวิตช์เป็นเปิดใช้ (สีน้ำเงิน) และตั้งค่าอีเมลสนับสนุนโครงการ
หากคุณได้รับข้อผิดพลาดในภายหลังใน Codelab นี้พร้อมข้อความ "CONFIGURATION_NOT_FOUND" ให้กลับมาที่ขั้นตอนนี้แล้วตรวจสอบงานอีกครั้ง
กำหนดค่าฐานข้อมูลเรียลไทม์
แอปใน Codelab นี้จัดเก็บข้อความแชทไว้ในฐานข้อมูลเรียลไทม์ของ Firebase ในส่วนนี้ เราจะสร้างฐานข้อมูลและกำหนดค่าการรักษาความปลอดภัยผ่านภาษาการกำหนดค่า JSON ชื่อกฎการรักษาความปลอดภัยของ Firebase
- ในคอนโซล Firebase ให้เลือก Realtime Database จากแผงการนำทางด้านซ้าย
- คลิกสร้างฐานข้อมูลเพื่อสร้างอินสแตนซ์ Realtime Database ใหม่ เมื่อมีข้อความแจ้ง ให้เลือกภูมิภาค
us-central1
แล้วคลิกถัดไป - เมื่อมีข้อความแจ้งเกี่ยวกับกฎความปลอดภัย ให้เลือกโหมดล็อก แล้วคลิกเปิดใช้
- เมื่อสร้างอินสแตนซ์ฐานข้อมูลแล้ว ให้เลือกแท็บกฎ จากนั้นอัปเดตการกำหนดค่ากฎด้วยข้อมูลต่อไปนี้
{ "rules": { "messages": { ".read": "auth.uid != null", ".write": "auth.uid != null" } } }
โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานของกฎการรักษาความปลอดภัย (รวมถึงเอกสารประกอบเกี่ยวกับตัวแปร "การตรวจสอบสิทธิ์") ในเอกสารด้านความปลอดภัยของ Realtime Database
กำหนดค่า Cloud Storage สำหรับ Firebase
- ในคอนโซล Firebase ให้เลือกพื้นที่เก็บข้อมูลจากแผงการนำทางด้านซ้าย
- คลิกเริ่มต้นใช้งานเพื่อเปิดใช้ Cloud Storage สำหรับโปรเจ็กต์
- ทำตามขั้นตอนในกล่องโต้ตอบเพื่อตั้งค่าที่เก็บข้อมูล โดยใช้ค่าเริ่มต้นที่แนะนำ
เชื่อมต่อกับทรัพยากร 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
ก็ได้