Android with Firebase Realtime Database - read | write | update | delete (ฉบับ ตามประสบการณ์ที่ได้ลองทำ)

ภาพรวมของการ CRUD กับ Firebase Realtime Database

การ Write - ใช้ setValue()
การ Read - ใช้ addValueEventListener หรือ addListenerForSingleValueEvent + getValue()
การ Update - ใช้  updateChildren() หรือใช้ setValue("value")
การ Delete - ใช้ได้ทั้ง removeValue() , setValue(null) , updateChildren()

แต่ก่อนจะทำการ Write , Read , Update , Delete จะต้องกำหนด Child Path ที่ต้องการก่อน
ตัวอย่าง การ Count Child Firebase Database และการกำหนด Child Path ดูได้ที่ :
https://trymydroid.blogspot.com/2019/08/android-firebase-realtime-database.html

เราสามารถนำตัวแปรมาใส่ในพาธได้ เช่น
val database = FirebaseDatabase.getInstance()
val databaseReference = database.reference.child("rooms/$roomId")

การดึงข้อมูลออกมาใช้งาน
สรุปรวมคือเมื่อเรากำหนด Listener แล้วจะได้ dataSnapshot เป็น ตัวแปร หรือ ข้อมูลที่ส่งกลับมา
แต่วิธีการดึงออกมาใช้งานขึ้นอยู่กับความเหมาะสมนะครับ



เพิ่มเติม (ไว้เป็นไอเดียร์ไว้เลือกใช้ตามความเหมาะสมครับ)
https://stackoverflow.com/questions/30933328/how-to-convert-firebase-data-to-java-object


การ Write หรือ Update (แบบ Single Value)
เราแค่กำหนด child ให้เป็นไปตามโครงสร้างที่เราต้องการและ setValue() โดยโยน object เข้าไปเลย พาธจะถูกสร้างขึ้นมาเอง

หรือในกรณีที่ต้อง Write หรือ Update Value ให้กับ Child ที่ต้องการแบบ Multiple Values ใช้ updateChildren()


ข้อควรระวัง 1.) เวลาอ่านข้อมูล คือ Listeners ของ Firebase เป็นแบบ asynchronous
ข้อควรระวัง 2.) เกี่ยวกับ Listeners และโครงสร้างฐานข้อมูลของ Firebase Realtime Database



การออกแบบโครงสร้าง แบบนี้ ข้อควรระวังคือ
ในตอนที่เราสร้าง listener  เพื่อ Read หรือดักการเปลี่ยนเปลี่ยนของ value ใน child members
เพื่อหวังจะดึง location ออกมาแบบนี้

        val database = FirebaseDatabase.getInstance()
        val databaseReference = database.reference
            .child("rooms")
            .child(roomId)
            .child("members")

        databaseReference.addListenerForSingleValueEvent(object : ValueEventListener{
            override fun onDataChange(dataSnapshot: DataSnapshot) {
             ..
             ..
            }
         )}


และวันข้างหน้าถ้ามีการเพิ่มฟังก์ชั่น change room password
เจ้าตัว onDataChange ตัวนี้ก็จะทำงานอีกครั้งเช่นกัน

ข้อควรระวัง 3.) ในตอนประกาศ reference เพื่อจะดึง value  


        val databaseReference = database.reference
        databaseReference  <<  อย่าเผลอใส่ reference เพิ่มมาแบบนี้
            .child("rooms")
            .child(roomId)
            .child("roomFeatures")
            .child("password")
   
       เพราะผลลัพธ์ที่ออกมาคือ password : 222 จะเด้งออกมา 2 ครั้ง ...ไล่โค้ดกันหัวฟูแน่ๆ

หลังจากนี้ใครฝึกดึงข้อมูลของมาได้แล้ว
อาจจะลองนำ GSON และฝึกสร้าง Model (ใช้ GSON เข้ามาช่วยในการ select ข้อมูลจะง่ายขึ้นมากๆ)

อยากลองฝึกใช้ GSON + ฝึกสร้าง Model ลองอ่านบทความเก่าของผมได้ที่นี่ครับ
Android Kotlin JSON Parsing using Retrofit + RecyclerView (List && Grid)

ปล.ใครฝึกจนสามารถดึงข้อมูลจาก https://jsonplaceholder.typicode.com/users/1ได้แล้วก็ จะทำให้เข้าใจง่ายขึ้นมากๆครับ

ปล.ถ้าระบบที่ทำขึ้นมาเป็นแนวๆ ChatRooms แนะนำให้อ่าน Best Practice ของการออกแบบฐานข้อมูล , ข้อจำกัด , และแนวทางที่นี่ครับ
https://firebase.google.com/docs/database/android/structure-data