1. ภาพรวม
รูปภาพ: แอป Friendly Chat ที่ใช้งานได้
ยินดีต้อนรับสู่ Codelab ของ Friendly Chat ใน Codelab นี้ คุณจะได้เรียนรู้วิธีใช้แพลตฟอร์ม Firebase เพื่อสร้างแอปแชทใน Android
สิ่งที่คุณจะได้เรียนรู้
- วิธีใช้การตรวจสอบสิทธิ์ Firebase เพื่ออนุญาตให้ผู้ใช้ลงชื่อเข้าใช้
- วิธีซิงค์ข้อมูลโดยใช้ฐานข้อมูลเรียลไทม์ของ Firebase
- วิธีจัดเก็บไฟล์ไบนารีใน Cloud Storage for Firebase
- วิธีใช้ Firebase Local Emulator Suite เพื่อพัฒนาแอป 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 นี้ เราได้เพิ่มการขึ้นต่อกันทั้งหมดที่คุณต้องการให้คุณแล้ว แต่คุณควรทำความเข้าใจวิธีเพิ่ม Firebase SDK ลงในแอป
build.gradle.kts
plugins {
id("com.android.application") version "8.0.0" apply false
id("com.android.library") version "8.0.0" apply false
id("org.jetbrains.kotlin.android") version "1.8.20" apply false
// The google-services plugin is required to parse the google-services.json file
id("com.google.gms.google-services") version "4.3.15" apply false
}
app/build.gradle.kts
plugins {
id("com.android.application")
id("kotlin-android")
id("com.google.gms.google-services")
}
android {
// ...
}
dependencies {
// ...
// Google Sign In SDK
implementation("com.google.android.gms:play-services-auth:20.5.0")
// Firebase SDK
implementation(platform("com.google.firebase:firebase-bom:32.0.0"))
implementation("com.google.firebase:firebase-database-ktx")
implementation("com.google.firebase:firebase-storage-ktx")
implementation("com.google.firebase:firebase-auth-ktx")
// Firebase UI Library
implementation("com.firebaseui:firebase-ui-auth:8.0.2")
implementation("com.firebaseui:firebase-ui-database:8.0.2")
}
3. ติดตั้ง Firebase CLI
ในโค้ดแล็บนี้ คุณจะได้ใช้ชุดโปรแกรมจำลอง Firebase เพื่อจำลอง 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 ในเว็บเบราว์เซอร์เพื่อดู UI ของ Firebase Emulator Suite
ปล่อยให้คำสั่ง emulators:start
ทำงานต่อไปสำหรับส่วนที่เหลือของโค้ดแล็บ
เชื่อมต่อแอป
ใน Android Studio ให้เปิด MainActivity.kt
จากนั้นเพิ่มโค้ดต่อไปนี้ภายในเมธอด onCreate
// When running in debug mode, connect to the Firebase Emulator Suite.
// "10.0.2.2" is a special IP address which allows the Android Emulator
// to connect to "localhost" on the host computer. The port values (9xxx)
// must match the values defined in the firebase.json file.
if (BuildConfig.DEBUG) {
Firebase.database.useEmulator("10.0.2.2", 9000)
Firebase.auth.useEmulator("10.0.2.2", 9099)
Firebase.storage.useEmulator("10.0.2.2", 9199)
}
5. เรียกใช้แอปเริ่มต้น
เพิ่ม google-services.json
หากต้องการให้แอป Android เชื่อมต่อกับ Firebase ได้ คุณต้องเพิ่มไฟล์ google-services.json
ภายในโฟลเดอร์ app
ของโปรเจ็กต์ Android เพื่อวัตถุประสงค์ของโค้ดแล็บนี้ เราได้จัดเตรียมไฟล์ JSON จำลองที่จะช่วยให้คุณเชื่อมต่อกับ Firebase Emulator Suite ได้
คัดลอกไฟล์ mock-google-services.json
ไปยังโฟลเดอร์ build-android-start/app
เป็น google-services.json
ดังนี้
cp mock-google-services.json build-android-start/app/google-services.json
ในขั้นตอนสุดท้ายของโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีสร้างโปรเจ็กต์ Firebase และแอป Firebase Android จริง เพื่อให้คุณแทนที่ไฟล์ JSON จำลองนี้ด้วยการกำหนดค่าของคุณเองได้
เรียกใช้แอป
ตอนนี้คุณได้นำเข้าโปรเจ็กต์ไปยัง Android Studio และเพิ่มไฟล์ JSON การกำหนดค่า Firebase แล้ว คุณก็พร้อมที่จะเรียกใช้แอปเป็นครั้งแรก
- เริ่มโปรแกรมจำลอง Android
- ใน Android Studio ให้คลิกเรียกใช้ (
) ในแถบเครื่องมือ
แอปควรเปิดในโปรแกรมจำลอง Android ในตอนนี้ คุณควรเห็นรายการข้อความว่างเปล่า และการส่งและรับข้อความจะใช้ไม่ได้ ในขั้นตอนถัดไปของโค้ดแล็บนี้ คุณจะตรวจสอบสิทธิ์ผู้ใช้เพื่อให้ผู้ใช้ใช้ Friendly Chat ได้
6. เปิดใช้การตรวจสอบสิทธิ์
แอปนี้จะใช้ฐานข้อมูลเรียลไทม์ของ Firebase เพื่อจัดเก็บข้อความแชททั้งหมด อย่างไรก็ตาม ก่อนที่จะเพิ่มข้อมูล เราควรตรวจสอบว่าแอปมีความปลอดภัยและมีเพียงผู้ใช้ที่ได้รับการตรวจสอบสิทธิ์เท่านั้นที่โพสต์ข้อความได้ ในขั้นตอนนี้ เราจะเปิดใช้การตรวจสอบสิทธิ์ Firebase และกำหนดค่ากฎความปลอดภัยของ Realtime Database
เพิ่มฟังก์ชันการลงชื่อเข้าใช้พื้นฐาน
จากนั้นเราจะเพิ่มโค้ดการตรวจสอบสิทธิ์ 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 Emulator Suite ให้เลือกแท็บฐานข้อมูลเรียลไทม์
- ลากและวางไฟล์
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
ด้วยโค้ดที่กำหนดไว้ด้านล่าง โค้ดนี้จะเพิ่มข้อความที่มีอยู่ทั้งหมดจากฐานข้อมูลเรียลไทม์ จากนั้นจะรอรายการใหม่ที่อยู่ภายใต้เส้นทาง 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 ของ Emulator Suite ให้กลับไปที่แท็บ Realtime Database แล้วเพิ่มข้อความใหม่ด้วยตนเอง ตรวจสอบว่าข้อความปรากฏในแอป Android โดยทำดังนี้
ขอแสดงความยินดี คุณเพิ่งเพิ่ม Realtime Database ลงในแอป
8. ส่งข้อความ
ติดตั้งใช้งานการส่งข้อความ
ในส่วนนี้ คุณจะเพิ่มความสามารถให้ผู้ใช้แอปส่ง SMS ได้ ข้อมูลโค้ดด้านล่างจะรอรับเหตุการณ์คลิกที่ปุ่มส่ง สร้างออบเจ็กต์ 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("")
}
ใช้การส่งข้อความรูปภาพ
ในส่วนนี้ คุณจะเพิ่มความสามารถให้ผู้ใช้แอปส่งข้อความรูปภาพได้ การสร้างข้อความรูปภาพทำได้โดยทำตามขั้นตอนต่อไปนี้
- เลือกรูปภาพ
- จัดการการเลือกรูปภาพ
- เขียนข้อความรูปภาพชั่วคราวไปยัง Realtime Database
- เริ่มอัปโหลดรูปภาพที่เลือก
- อัปเดต URL ของข้อความรูปภาพเป็น URL ของรูปภาพที่อัปโหลดเมื่ออัปโหลดเสร็จสมบูรณ์
เลือกรูปภาพ
หากต้องการเพิ่มรูปภาพ Codelab นี้จะใช้ Cloud Storage for Firebase Cloud Storage เป็นที่เก็บข้อมูลไบนารีของแอปที่เหมาะสม
จัดการการเลือกรูปภาพและเขียนข้อความชั่วคราว
เมื่อผู้ใช้เลือกรูปภาพแล้ว ระบบจะเปิดใช้การเลือกรูปภาพ Intent
ซึ่งได้มีการติดตั้งใช้งานในโค้ดที่ส่วนท้ายของเมธอด onCreate()
แล้ว เมื่อเสร็จแล้ว ระบบจะเรียกใช้เมธอด MainActivity
's onImageSelected()
การใช้ข้อมูลโค้ดด้านล่างจะช่วยให้คุณเขียนข้อความที่มี 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
)
}
}
ทดสอบการส่งข้อความ
- ใน Android Studio ให้คลิกปุ่ม
เรียกใช้
- ใน Android Emulator ให้ป้อนข้อความ แล้วแตะปุ่มส่ง ข้อความใหม่ควรปรากฏใน UI ของแอปและใน UI ของ Firebase Emulator Suite
- ในโปรแกรมจำลอง Android ให้แตะรูปภาพ "+" เพื่อเลือกรูปภาพจากอุปกรณ์ ข้อความใหม่ควรแสดงก่อนพร้อมกับรูปภาพตัวยึดตำแหน่ง จากนั้นจึงแสดงพร้อมกับรูปภาพที่เลือกเมื่ออัปโหลดรูปภาพเสร็จสมบูรณ์ ข้อความใหม่ควรปรากฏใน UI ของ 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 Local Emulator Suite ในการพัฒนาและทดสอบ
10. ไม่บังคับ: สร้างและตั้งค่าโปรเจ็กต์ Firebase
ในขั้นตอนนี้ คุณจะสร้างโปรเจ็กต์ Firebase จริงและแอป Android ของ Firebase เพื่อใช้กับ Codelab นี้ นอกจากนี้ คุณยังจะเพิ่มการกำหนดค่า Firebase เฉพาะแอปไปยังแอปด้วย และสุดท้าย คุณจะตั้งค่าทรัพยากร Firebase จริงเพื่อใช้กับแอป
สร้างโปรเจ็กต์ Firebase
- ลงชื่อเข้าใช้คอนโซล Firebase โดยใช้บัญชี Google
- คลิกปุ่มเพื่อสร้างโปรเจ็กต์ใหม่ แล้วป้อนชื่อโปรเจ็กต์ (เช่น
FriendlyChat
)
- คลิกต่อไป
- หากได้รับแจ้ง ให้อ่านและยอมรับข้อกำหนดของ Firebase แล้วคลิกต่อไป
- (ไม่บังคับ) เปิดใช้ความช่วยเหลือจาก AI ในคอนโซล Firebase (เรียกว่า "Gemini ใน Firebase")
- สำหรับ Codelab นี้ คุณไม่จำเป็นต้องใช้ Google Analytics ดังนั้นให้ปิดตัวเลือก Google Analytics
- คลิกสร้างโปรเจ็กต์ รอให้ระบบจัดสรรโปรเจ็กต์ แล้วคลิกดำเนินการต่อ
อัปเกรดแพ็กเกจราคาของ Firebase
หากต้องการใช้ Cloud Storage สำหรับ Firebase โปรเจ็กต์ Firebase ของคุณต้องอยู่ในแพ็กเกจราคาแบบจ่ายเมื่อใช้ (Blaze) ซึ่งหมายความว่าโปรเจ็กต์ดังกล่าวลิงก์กับบัญชีการเรียกเก็บเงินในระบบคลาวด์
- บัญชีสำหรับการเรียกเก็บเงินของ Cloud ต้องมีวิธีการชำระเงิน เช่น บัตรเครดิต
- หากเพิ่งเริ่มใช้ Firebase และ Google Cloud โปรดตรวจสอบว่าคุณมีสิทธิ์รับเครดิต$300 และบัญชีสำหรับการเรียกเก็บเงินในระบบคลาวด์แบบทดลองใช้ฟรีหรือไม่
- หากคุณกำลังทำ Codelab นี้เป็นส่วนหนึ่งของกิจกรรม โปรดสอบถามผู้จัดว่ามีเครดิต Cloud ให้หรือไม่
หากต้องการอัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ให้ทำตามขั้นตอนต่อไปนี้
- ในคอนโซล Firebase ให้เลือกอัปเกรดแพ็กเกจ
- เลือกแพ็กเกจ Blaze ทำตามวิธีการบนหน้าจอเพื่อลิงก์บัญชีสำหรับการเรียกเก็บเงินใน Cloud กับโปรเจ็กต์
หากคุณต้องสร้างบัญชีสำหรับการเรียกเก็บเงินใน Cloud เป็นส่วนหนึ่งของการอัปเกรดนี้ คุณอาจต้องกลับไปที่ขั้นตอนการอัปเกรดใน Firebase Console เพื่อทำการอัปเกรดให้เสร็จสมบูรณ์
เพิ่ม 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 ให้เลือก File > Sync Project with Gradle Files นอกจากนี้ คุณอาจต้องเรียกใช้สร้าง/ล้างโปรเจ็กต์และสร้าง/สร้างโปรเจ็กต์ใหม่เพื่อให้การเปลี่ยนแปลงการกำหนดค่ามีผล
กำหนดค่าการตรวจสอบสิทธิ์ Firebase
ก่อนที่แอปจะเข้าถึง Firebase Authentication API ในนามของผู้ใช้ได้ คุณต้องเปิดใช้ Firebase Authentication และผู้ให้บริการลงชื่อเข้าใช้ที่ต้องการใช้ในแอป
- ในคอนโซล Firebase ให้เลือกการตรวจสอบสิทธิ์จากแผงการนำทางด้านซ้าย
- เลือกแท็บวิธีการลงชื่อเข้าใช้
- คลิกอีเมล/รหัสผ่าน แล้วสลับปุ่มเปิด/ปิดเป็นเปิด (สีน้ำเงิน)
- คลิก Google จากนั้นสลับปุ่มเปิด/ปิดเป็นเปิด (สีน้ำเงิน) และตั้งค่าอีเมลสนับสนุนโปรเจ็กต์
หากได้รับข้อผิดพลาดในภายหลังใน Codelab นี้พร้อมข้อความ "CONFIGURATION_NOT_FOUND" ให้กลับมาที่ขั้นตอนนี้และตรวจสอบงานของคุณอีกครั้ง
ตั้งค่า Realtime Database
แอปในโค้ดแล็บนี้จะจัดเก็บข้อความแชทในฐานข้อมูลเรียลไทม์ของ Firebase ในส่วนนี้ เราจะสร้างฐานข้อมูลและกำหนดค่าความปลอดภัยผ่านภาษาการกำหนดค่า JSON ที่เรียกว่ากฎความปลอดภัยของ Firebase
- ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายสร้าง แล้วเลือก Realtime Database
- คลิกสร้างฐานข้อมูล
- เลือกตำแหน่งสำหรับฐานข้อมูล แล้วคลิกถัดไป
สำหรับแอปจริง คุณควรเลือกตำแหน่งที่อยู่ใกล้กับผู้ใช้ - คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎความปลอดภัย
ในขั้นตอนถัดไปของ Codelab นี้ คุณจะเพิ่มกฎความปลอดภัยเพื่อรักษาความปลอดภัยของข้อมูล อย่าเผยแพร่หรือเปิดเผยแอปต่อสาธารณะโดยไม่ได้เพิ่มกฎความปลอดภัยสำหรับฐานข้อมูล - คลิกสร้าง
- เมื่อสร้างอินสแตนซ์ฐานข้อมูลแล้ว ให้เลือกแท็บกฎ จากนั้นอัปเดตการกำหนดค่ากฎด้วยข้อมูลต่อไปนี้
{ "rules": { "messages": { ".read": "auth.uid != null", ".write": "auth.uid != null" } } }
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานของกฎความปลอดภัย (รวมถึงเอกสารประกอบเกี่ยวกับตัวแปร "auth") ได้ที่เอกสารประกอบด้านความปลอดภัยของ Realtime Database
ตั้งค่า Cloud Storage for Firebase
- ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายสร้าง แล้วเลือก Storage
- คลิกเริ่มต้นใช้งาน
- เลือกตำแหน่งสำหรับที่เก็บข้อมูลเริ่มต้น
ที่เก็บข้อมูลในUS-WEST1
,US-CENTRAL1
และUS-EAST1
จะใช้ประโยชน์จากระดับ"ใช้งานฟรีเสมอ" สำหรับ Google Cloud Storage ได้ ที่เก็บข้อมูลในตำแหน่งอื่นๆ ทั้งหมดจะเป็นไปตามราคาและการใช้งาน Google Cloud Storage - คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎความปลอดภัย
ในภายหลังใน Codelab นี้ คุณจะเพิ่มกฎความปลอดภัยเพื่อรักษาความปลอดภัยของข้อมูล อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่ได้เพิ่มกฎความปลอดภัยสำหรับที่เก็บข้อมูล - คลิกสร้าง
เชื่อมต่อกับทรัพยากร 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