1. ภาพรวม
รูปภาพ: แอป Chat ที่เหมาะสำหรับการทำงาน
ยินดีต้อนรับสู่ Friendly Chat Codelab ใน 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
ในโค้ดแล็บนี้ เราได้เพิ่มการพึ่งพาทั้งหมดที่จําเป็นไว้ให้คุณแล้ว แต่คุณก็ควรทําความเข้าใจวิธีเพิ่ม 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
คุณต้องเพิ่มไฟล์ google-services.json
ไว้ในโฟลเดอร์ app
ของโปรเจ็กต์ Android เพื่อให้แอป Android เชื่อมต่อกับ Firebase ได้ เรามีไฟล์ JSON จําลองไว้ให้เพื่อวัตถุประสงค์ของโค้ดแล็บนี้ ซึ่งจะช่วยให้คุณเชื่อมต่อกับชุดโปรแกรมจําลอง Firebase ได้
คัดลอกไฟล์ mock-google-services.json
ไปยังโฟลเดอร์ build-android-start/app
เป็น google-services.json
cp mock-google-services.json build-android-start/app/google-services.json
ในขั้นตอนสุดท้ายของโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีสร้างโปรเจ็กต์ 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 ระบบควรส่งคุณไปยังหน้าจอลงชื่อเข้าใช้ทันที แตะปุ่มลงชื่อเข้าใช้ด้วยอีเมล แล้วสร้างบัญชี หากติดตั้งใช้งานทุกอย่างอย่างถูกต้อง ระบบจะส่งคุณไปยังหน้าจอการรับส่งข้อความ
หลังจากลงชื่อเข้าใช้แล้ว ให้เปิด UI ของชุดโปรแกรมจำลอง Firebase ในเบราว์เซอร์ แล้วคลิกแท็บการตรวจสอบสิทธิ์เพื่อดูบัญชีผู้ใช้ที่ลงชื่อเข้าใช้ครั้งแรกนี้
7. อ่านข้อความ
ในขั้นตอนนี้ เราจะเพิ่มฟังก์ชันการอ่านและแสดงข้อความที่จัดเก็บไว้ใน Realtime Database
นําเข้าข้อความตัวอย่าง
- ใน UI ของชุดโปรแกรมจำลอง Firebase ให้เลือกแท็บฐานข้อมูลเรียลไทม์
- ลากและวางไฟล์
initial_messages.json
จากสําเนาที่เก็บข้อมูลโค้ดแล็บในเครื่องลงในเครื่องมือดูข้อมูล
ตอนนี้คุณควรมีข้อความ 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 Realtime Database ซึ่งจะเพิ่มองค์ประกอบใหม่ลงใน 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. ส่งข้อความ
ใช้การส่งข้อความ
ในส่วนนี้ คุณจะเพิ่มความสามารถในการส่ง 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 ของรูปภาพที่อัปโหลดเมื่ออัปโหลดเสร็จแล้ว
เลือกรูปภาพ
โค้ดแล็บนี้ใช้ Cloud Storage for 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
)
}
}
ทดสอบการส่งข้อความ
- ใน Android Studio ให้คลิกปุ่ม Run
- ใน Android Emulator ให้ป้อนข้อความ แล้วแตะปุ่มส่ง ข้อความใหม่ควรปรากฏใน UI ของแอปและใน UI ของชุดโปรแกรมจำลอง Firebase
- ในโปรแกรมจำลอง Android ให้แตะรูปภาพ "+" เพื่อเลือกรูปภาพจากอุปกรณ์ ข้อความใหม่ควรปรากฏขึ้นพร้อมกับรูปภาพตัวยึดตําแหน่งก่อน จากนั้นจะแสดงรูปภาพที่เลือกเมื่ออัปโหลดรูปภาพเสร็จสมบูรณ์ ข้อความใหม่ควรปรากฏใน UI ของชุดโปรแกรมจำลองด้วย โดยเฉพาะอย่างยิ่งในฐานะออบเจ็กต์ในแท็บฐานข้อมูลเรียลไทม์และเป็น Blob ในแท็บพื้นที่เก็บข้อมูล
9. ยินดีด้วย
คุณเพิ่งสร้างแอปพลิเคชันแชทแบบเรียลไทม์โดยใช้ Firebase
สิ่งที่ได้เรียนรู้
- การตรวจสอบสิทธิ์ Firebase
- ฐานข้อมูลเรียลไทม์ของ Firebase
- Cloud Storage for Firebase
ต่อไป ให้ลองใช้สิ่งที่ได้เรียนรู้ในโค้ดแล็บนี้เพื่อเพิ่ม Firebase ลงในแอป Android ของคุณเอง ดูข้อมูลเพิ่มเติมเกี่ยวกับ Firebase ได้ที่ firebase.google.com
หากต้องการดูวิธีตั้งค่าโปรเจ็กต์ Firebase จริง และใช้ทรัพยากร Firebase จริง (แทนโปรเจ็กต์สาธิตและทรัพยากรจำลองเท่านั้น) ให้ไปที่ขั้นตอนถัดไป
หมายเหตุ: แม้คุณจะตั้งค่าโปรเจ็กต์ Firebase จริงแล้ว และโดยเฉพาะเมื่อเริ่มสร้างแอปจริง เราขอแนะนำให้ใช้ Firebase Local Emulator Suite สําหรับการพัฒนาและการทดสอบ
10. ไม่บังคับ: สร้างและตั้งค่าโปรเจ็กต์ Firebase
ในขั้นตอนนี้ คุณจะได้สร้างโปรเจ็กต์ Firebase จริงและแอป Firebase สำหรับ Android เพื่อใช้กับโค้ดแล็บนี้ นอกจากนี้ คุณยังเพิ่มการกําหนดค่า Firebase สําหรับแอปโดยเฉพาะลงในแอปด้วย และสุดท้าย คุณจะต้องตั้งค่าทรัพยากร Firebase จริงเพื่อใช้กับแอป
สร้างโปรเจ็กต์ Firebase
- ไปที่คอนโซล Firebase ในเบราว์เซอร์
- เลือกเพิ่มโปรเจ็กต์
- เลือกหรือป้อนชื่อโปรเจ็กต์ คุณใช้ชื่อใดก็ได้
- คุณไม่จำเป็นต้องใช้ Google Analytics สําหรับโค้ดแล็บนี้ คุณจึงข้ามการเปิดใช้สําหรับโปรเจ็กต์ได้
- คลิกสร้างโปรเจ็กต์ เมื่อโปรเจ็กต์พร้อมแล้ว ให้คลิกต่อไป
อัปเกรดแพ็กเกจราคาของ Firebase
หากต้องการใช้พื้นที่เก็บข้อมูลระบบคลาวด์สำหรับ Firebase โปรเจ็กต์ Firebase ของคุณต้องใช้แพ็กเกจราคาแบบจ่ายเมื่อใช้ (Blaze) ซึ่งหมายความว่าโปรเจ็กต์จะลิงก์กับบัญชีการเรียกเก็บเงินระบบคลาวด์
- บัญชีการเรียกเก็บเงินระบบคลาวด์ต้องมีวิธีการชำระเงิน เช่น บัตรเครดิต
- หากคุณเพิ่งเริ่มใช้ Firebase และ Google Cloud ให้ตรวจสอบว่าคุณมีสิทธิ์รับเครดิตมูลค่า$300 และบัญชีการเรียกเก็บเงินระบบคลาวด์แบบทดลองใช้ฟรีหรือไม่
- หากคุณทำ Codelab นี้เป็นส่วนหนึ่งของกิจกรรม โปรดสอบถามผู้จัดว่ามีเครดิต Cloud เหลืออยู่ไหม
หากต้องการอัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ให้ทำตามขั้นตอนต่อไปนี้
- ในคอนโซล Firebase ให้เลือกอัปเกรดแพ็กเกจ
- เลือกแพ็กเกจ Blaze ทำตามวิธีการบนหน้าจอเพื่อลิงก์บัญชีสำหรับการเรียกเก็บเงินใน Cloud กับโปรเจ็กต์
หากจำเป็นต้องสร้างบัญชีสำหรับการเรียกเก็บเงินใน Cloud เป็นส่วนหนึ่งของการอัปเกรดนี้ คุณอาจต้องกลับไปที่ขั้นตอนการอัปเกรดในคอนโซล Firebase เพื่อดำเนินการอัปเกรดให้เสร็จสมบูรณ์
เพิ่ม Firebase ไปยังโปรเจ็กต์ Android
ก่อนเริ่มขั้นตอนนี้ ให้รับแฮช SHA1 ของแอป เรียกใช้คําสั่งต่อไปนี้จากไดเรกทอรี build-android-start
ในเครื่องเพื่อระบุ SHA1 ของคีย์แก้ไขข้อบกพร่อง
./gradlew signingReport Store: /Users/<username>/.android/debug.keystore Alias: AndroidDebugKey MD5: A5:88:41:04:8F:06:59:6A:AE:33:76:87:AA:AD:19:23 SHA1: A7:89:F5:06:A8:07:A1:22:EC:90:6A:A6:EA:C3:D4:8B:3A:30:AB:18 SHA-256: 05:A2:2A:35:EE:F2:51:23:72:4D:72:67:A5:6A:8A:58:22:2C:00:A6:AB:F6:45:D5:A1:82:D8:90:A4:69:C8:FE Valid until: Wednesday, August 10, 2044
คุณควรเห็นเอาต์พุตบางส่วนดังที่แสดงด้านบน บรรทัดที่สำคัญคือแฮช SHA1
หากไม่พบแฮช SHA1 โปรดดูข้อมูลเพิ่มเติมในหน้านี้
กลับไปที่คอนโซล Firebase แล้วทําตามขั้นตอนต่อไปนี้เพื่อลงทะเบียนโปรเจ็กต์ Android กับโปรเจ็กต์ Firebase
- จากหน้าจอภาพรวมของโปรเจ็กต์ใหม่ ให้คลิกไอคอน Android เพื่อเปิดเวิร์กโฟลว์การตั้งค่า
- ในหน้าจอถัดไป ให้ป้อน
com.google.firebase.codelab.friendlychat
เป็นชื่อแพ็กเกจของแอป - คลิกลงทะเบียนแอป แล้วคลิกดาวน์โหลด google-services.json เพื่อดาวน์โหลดไฟล์การกําหนดค่า Firebase
- คัดลอกไฟล์
google-services.json
ไปยังไดเรกทอรีapp
ของโปรเจ็กต์ Android - ข้ามขั้นตอนถัดไปที่แสดงในเวิร์กโฟลว์การตั้งค่าของคอนโซล (ระบบได้ดำเนินการขั้นตอนเหล่านี้ให้คุณแล้วในโปรเจ็กต์
build-android-start
) - ตรวจสอบว่าแอปของคุณใช้ทรัพยากร Dependency ทั้งหมดได้โดยการซิงค์โปรเจ็กต์กับไฟล์ Gradle จากแถบเครื่องมือของ Android Studio ให้เลือกไฟล์ > ซิงค์โปรเจ็กต์กับไฟล์ Gradle นอกจากนี้ คุณอาจต้องเรียกใช้สร้าง/ล้างโปรเจ็กต์และสร้าง/สร้างโปรเจ็กต์อีกครั้งเพื่อให้การเปลี่ยนแปลงการกําหนดค่ามีผล
กำหนดค่าการตรวจสอบสิทธิ์ Firebase
คุณต้องเปิดใช้การตรวจสอบสิทธิ์ Firebase และผู้ให้บริการลงชื่อเข้าใช้ที่ต้องการใช้ในแอปก่อน เพื่อให้แอปเข้าถึง Firebase Authentication API ในนามของผู้ใช้ได้
- ในคอนโซล Firebase ให้เลือกการตรวจสอบสิทธิ์จากแผงการนำทางด้านซ้าย
- เลือกแท็บวิธีการลงชื่อเข้าใช้
- คลิกอีเมล/รหัสผ่าน แล้วสลับสวิตช์เป็นเปิดใช้ (สีน้ำเงิน)
- คลิก Google จากนั้นสลับสวิตช์เป็นเปิดใช้ (สีน้ำเงิน) และตั้งค่าอีเมลการสนับสนุนโปรเจ็กต์
หากพบข้อผิดพลาดในภายหลังในโค้ดแล็บนี้พร้อมข้อความ "CONFIGURATION_NOT_FOUND" ให้กลับมาที่ขั้นตอนนี้และตรวจสอบงานอีกครั้ง
ตั้งค่า Realtime Database
แอปในโค้ดแล็บนี้จะจัดเก็บข้อความแชทในฐานข้อมูลเรียลไทม์ของ Firebase ในส่วนนี้ เราจะสร้างฐานข้อมูลและกำหนดค่าความปลอดภัยผ่านภาษาการกําหนดค่า JSON ที่เรียกว่ากฎความปลอดภัยของ Firebase
- ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายสร้าง แล้วเลือก ฐานข้อมูลเรียลไทม์
- คลิกสร้างฐานข้อมูล
- เลือกตำแหน่งสำหรับฐานข้อมูล แล้วคลิกถัดไป
สำหรับแอปจริง คุณควรเลือกตำแหน่งที่อยู่ใกล้กับผู้ใช้ - คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎความปลอดภัย
ในขั้นตอนถัดไปของโค้ดแล็บนี้ คุณจะเพิ่มกฎความปลอดภัยเพื่อรักษาความปลอดภัยให้กับข้อมูล อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่เพิ่มกฎความปลอดภัยสําหรับฐานข้อมูล - คลิกสร้าง
- เมื่อสร้างอินสแตนซ์ฐานข้อมูลแล้ว ให้เลือกแท็บกฎ จากนั้นอัปเดตการกําหนดค่ากฎด้วยข้อมูลต่อไปนี้
{ "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 - คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎการรักษาความปลอดภัย
ในภายหลังในโค้ดแล็บนี้ คุณจะต้องเพิ่มกฎการรักษาความปลอดภัยเพื่อรักษาความปลอดภัยให้ข้อมูล อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่เพิ่มกฎความปลอดภัยสำหรับที่เก็บข้อมูล - คลิกสร้าง
เชื่อมต่อกับทรัพยากร Firebase
ในขั้นตอนก่อนหน้าของโค้ดแล็บนี้ คุณได้เพิ่มข้อมูลต่อไปนี้ลงใน MainActivity.kt
บล็อกแบบมีเงื่อนไขนี้เชื่อมต่อโปรเจ็กต์ Android กับชุดโปรแกรมจำลอง Firebase
// 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