Firebase Realtime Database คือฐานข้อมูล JSON บนคลาวด์แบบเวลาจริงที่เปิดตัวโดย Google ในปี 2012 สำหรับแอปพลิเคชันมือถือและเว็บ ข้อมูลทั้งหมดจะถูกเก็บไว้ในต้นไม้ JSON ขนาดใหญ่ต้นเดียวและซิงโครไนซ์ระหว่างไคลเอ็นต์ที่เชื่อมต่อกันแบบเวลาจริงผ่านการเชื่อมต่อ WebSocket ตามเอกสารอย่างเป็นทางการ Firebase, 2025, Realtime Database สามารถให้บริการได้สูงสุด 200,000 การเชื่อมต่อและรองรับสูงสุด 1,000 การเขียนพร้อมกันต่อวินาที ฐานข้อมูลไม่ต้องใช้โครงสร้างพื้นฐานเซิร์ฟเวอร์และให้ SDK สำหรับ iOS, Android, Web และแพลตฟอร์มเซิร์ฟเวอร์
หัวข้อสำคัญ
Firebase Realtime Database คือฐานข้อมูล NoSQL บนคลาวด์ที่เก็บและซิงโครไนซ์ข้อมูลแบบเวลาจริงระหว่างไคลเอ็นต์ที่เชื่อมต่อทั้งหมด เปิดตัวในปี 2012 ในชื่อ Firebase (ก่อนการซื้อกิจการโดย Google) มันกลายเป็นฐานข้อมูลเวลาจริงบนคลาวด์ตัวแรกสำหรับนักพัฒนามือถือ ข้อมูลจะแสดงในรูปแบบ JSON และจัดระเบียบเป็นต้นไม้แบบลำดับชั้น โดยแต่ละโหนดมีเส้นทางที่ไม่ซ้ำกัน
คุณค่าหลักของ Realtime Database คือการซิงโครไนซ์ในตัว เมื่อแอปพลิเคชันเปลี่ยนแปลงข้อมูลบนอุปกรณ์ใดๆ ไคลเอ็นต์อื่นๆ ที่เชื่อมต่ออยู่ทั้งหมดจะได้รับการอัปเดตทันทีผ่านการเชื่อมต่อแบบถาวร ซึ่งช่วยลดความจำเป็นที่นักพัฒนาจะต้อง implement กลไกการซิงโครไนซ์ของตนเอง, WebSocket server หรือ REST API สำหรับการถ่ายโอนข้อมูลระหว่างไคลเอ็นต์
ฐานข้อมูลให้ SDK สำหรับทุกแพลตฟอร์มหลัก: Android (Java, Kotlin), iOS (Swift, Objective-C), Web (JavaScript) และสภาพแวดล้อมเซิร์ฟเวอร์ผ่าน Admin SDK ตามข้อมูลของ Google Realtime Database ถูกใช้ในโครงการ Firebase ที่ใช้งานอยู่มากกว่า 1.5 ล้านโครงการทั่วโลก แม้ว่า Firestore ที่ทันสมัยกว่าจะเกิดขึ้น Realtime Database ก็ยังคงเป็นตัวเลือกยอดนิยมสำหรับโครงการที่มีโครงสร้างข้อมูลที่เรียบง่าย
แตกต่างจากฐานข้อมูลเชิงสัมพันธ์ Realtime Database ไม่ใช้ตารางและแถว ข้อมูลทั้งหมดเป็นต้นไม้ JSON เดียวที่มีลักษณะเหมือนออบเจกต์ JavaScript ที่ซ้อนกัน ตัวอย่างเช่น สำหรับการเก็บผู้ใช้และข้อความของพวกเขา จะสร้างลำดับชั้น: users/userId/name และ messages/messageId/text แต่ละเส้นทางในต้นไม้เป็นสตริง และสามารถเข้าถึงข้อมูลได้โดยตรงผ่านเส้นทางนี้
{
"users": {
"user1": {
"name": "อีวาน เปตรอฟ",
"email": "ivan@example.com"
},
"user2": {
"name": "มาเรีย โซโคโลวา",
"email": "maria@example.com"
}
},
"messages": {
"-Nabc123": {
"text": "สวัสดี!",
"userId": "user1"
}
}
}
คุณสมบัติที่สำคัญ — การซ้อนกันลึกส่งผลต่อประสิทธิภาพ เมื่อแอปพลิเคชันอ่านข้อมูลตามเส้นทางที่กำหนด มันจะโหลดโหนดลูกทั้งหมดของเส้นทางนั้น ดังนั้นจึงแนะนำให้ออกแบบโครงสร้างข้อมูลให้แบนที่สุดเท่าที่จะทำได้ หลีกเลี่ยงการซ้อนกันลึกเกิน 3-4 ระดับ เพื่อแก้ไขปัญหานี้ ใช้การ Denormalization ข้อมูล — การทำซ้ำข้อมูลในโหนดต่างๆ ของต้นไม้
Realtime Database และ Firestore มักถูกเปรียบเทียบเป็นฐานข้อมูลเวลาจริงบนคลาวด์สองตัวจาก Google การเลือกระหว่างพวกเขาขึ้นอยู่กับความต้องการเฉพาะของโครงการ: ความซับซ้อนของคำสั่ง ความสอดคล้องที่ต้องการ และโหลดที่คาดหวัง การเข้าใจจุดแข็งของแต่ละฐานข้อมูลช่วยในการตัดสินใจทางสถาปัตยกรรมที่ถูกต้อง
ข้อได้เปรียบหลักของ Realtime Database คือความหน่วงในการซิงโครไนซ์ต่ำ เนื่องจากข้อมูลทั้งหมดถูกเก็บในต้นไม้ JSON เดียวโดยไม่มีชั้นนามธรรมเพิ่มเติม การซิงโครไนซ์จึงเกิดขึ้นเร็วกว่าใน Firestore สำหรับแอปพลิเคชันที่ความเร็วในการส่งอัปเดตมีความสำคัญ (แชท, เกมออนไลน์, ระบบการแก้ไขร่วมกัน) Realtime Database อาจเป็นตัวเลือกที่เหมาะสมกว่า
Realtime Database เหมาะกับสถานการณ์ที่มีโครงสร้างข้อมูลเรียบง่ายและความถี่ในการอัปเดตสูง ตัวอย่างทั่วไป: แชท, การกดไลค์แบบเวลาจริง, ตัวบ่งชี้การพิมพ์, สถานะการปรากฏตัวของผู้ใช้ นอกจากนี้ยังเป็นตัวเลือกที่ดีสำหรับต้นแบบและโครงการที่มีงบประมาณจำกัด เนื่องจากการกำหนดราคาขึ้นอยู่กับปริมาณข้อมูล ไม่ใช่จำนวนการดำเนินการ
ในทางกลับกัน สำหรับแอปพลิเคชันที่มีคำสั่งซับซ้อน (การกรองหลายฟิลด์, การเรียงลำดับ, การรวม) Firestore มีความสามารถที่ทรงพลังกว่ามาก Realtime Database รองรับเฉพาะการกรองตามพารามิเตอร์เดียวและไม่สามารถเรียงลำดับผลลัพธ์ตามหลายฟิลด์พร้อมกันได้ หากโครงการวางแผนการวิเคราะห์ข้อมูลที่ซับซ้อนบนฝั่งไคลเอ็นต์ Firestore จะเป็นตัวเลือกที่ใช้งานได้จริงมากกว่า
Realtime Database ใช้การเชื่อมต่อ WebSocket แบบถาวรสำหรับการซิงโครไนซ์ข้อมูลสองทาง เมื่อไคลเอ็นต์เรียก setValue หรือ updateChildren บนเส้นทางที่กำหนด ข้อมูลจะถูกส่งไปยังเซิร์ฟเวอร์ Firebase ผ่านช่องทางที่เปิดอยู่ เซิร์ฟเวอร์จะใช้การเปลี่ยนแปลงและแจกจ่ายอัปเดตให้กับไคลเอ็นต์ที่สมัครสมาชิกทั้งหมดภายในมิลลิวินาที แต่ละการเชื่อมต่อจะถูกระบุด้วยคีย์เซสชันที่ไม่ซ้ำกัน
กลไกการสมัครสมาชิกทำงานผ่าน listeners นักพัฒนาสามารถสมัครสมาชิกการเปลี่ยนแปลงของโหนดเฉพาะ (addListenerForSingleValueEvent) หรือรับอัปเดตต่อเนื่อง (addValueEventListener) ทุกครั้งที่มีการเปลี่ยนแปลงข้อมูล callback onDataChange จะถูกเรียกพร้อมกับภาพรวมข้อมูลทั้งหมดตามเส้นทางที่ระบุ ซึ่งแตกต่างจาก Firestore ที่จะได้รับเฉพาะเอกสารที่เปลี่ยนแปลงเท่านั้น — ใน Realtime Database ข้อมูลทั้งหมดของโหนดจะถูกโหลดเสมอ
Realtime Database รองรับโหมดออฟไลน์บน Android และ iOS ผ่านการแคชบนดิสก์ SDK เก็บสำเนาข้อมูลในเครื่องและดำเนินการเขียนต่อไปเมื่อไม่มีเครือข่าย เมื่อการเชื่อมต่อถูกกู้คืน การเปลี่ยนแปลงที่สะสมทั้งหมดจะถูกส่งไปยังเซิร์ฟเวอร์ สำหรับการแก้ไขข้อขัดแย้งจะใช้กลยุทธ์ last-write-wins แต่นักพัฒนาสามารถ implement logic ที่กำหนดเองผ่าน ServerValue.TIMESTAMP สำหรับการแก้ไขการชนกัน
val database = FirebaseDatabase.getInstance()
val myRef = database.getReference("messages")
// การเขียนข้อมูล
myRef.push().setValue(
hashMapOf(
"text" to "ข้อความใหม่",
"timestamp" to ServerValue.TIMESTAMP
)
)
// การอ่านด้วยการอัปเดตต่อเนื่อง
myRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val data = snapshot.getValue()
Log.d("TAG", "ข้อมูล: $data")
}
override fun onCancelled(error: DatabaseError) {
Log.w("TAG", "ข้อผิดพลาด: ${error.message}")
}
})
เพื่อเพิ่มประสิทธิภาพการรับส่งข้อมูลและประสิทธิภาพ แนะนำให้ใช้ child listeners แทน value listeners เมื่อต้องการติดตามการเปลี่ยนแปลงของโหนดลูกเฉพาะ ChildEventListener ให้ callback แยกต่างหากสำหรับการเพิ่ม, แก้ไข, ลบ และย้ายองค์ประกอบลูก ซึ่งช่วยให้ควบคุมการอัปเดต UI ได้แม่นยำยิ่งขึ้นและหลีกเลี่ยงการวาดรายการทั้งหมดใหม่ทุกครั้งที่มีการเปลี่ยนแปลงข้อมูล
Realtime Database ใช้ภาษากฎแบบประกาศสำหรับการควบคุมการเข้าถึงข้อมูล กฎจะอธิบายว่าใครสามารถอ่านและเขียนข้อมูลตามแต่ละเส้นทางของต้นไม้ JSON กฎจะถูกตรวจสอบบนเซิร์ฟเวอร์ Firebase ก่อนทุกคำขอและไม่ต้องใช้ logic ฝั่งเซิร์ฟเวอร์สำหรับการอนุญาต กฎรองรับตัวแปร, ออบเจกต์ในตัว และฟังก์ชันสำหรับการกำหนดค่าการเข้าถึงที่ยืดหยุ่น
โดยค่าเริ่มต้น การเข้าถึงฐานข้อมูลจะถูกปฏิเสธสำหรับผู้ใช้ทั้งหมด นักพัฒนาจะเปิดการเข้าถึงตามลำดับโดยใช้กฎ ".read" และ ".write" ในระดับต่างๆ ของต้นไม้ เงื่อนไขสามารถตรวจสอบการยืนยันตัวตนผ่านตัวแปร auth, ประเภทคำขอ (read/write) และข้อมูลที่มีอยู่ผ่านออบเจกต์ data นอกจากนี้ กฎยังรองรับการตรวจสอบข้อมูลที่เขียนผ่านออบเจกต์ newData
{
"rules": {
"users": {
"$uid": {
// เฉพาะเจ้าของเท่านั้นที่สามารถอ่านข้อมูลของตนเอง
".read": "$uid === auth.uid",
// เฉพาะเจ้าของเท่านั้นที่สามารถเขียน
".write": "$uid === auth.uid",
// การตรวจสอบฟิลด์เมื่อเขียน
".validate": "newData.hasChildren(['name', 'email'])"
}
},
"messages": {
// ผู้ใช้ที่ผ่านการยืนยันตัวตนใดๆ ก็สามารถอ่าน
".read": "auth !== null",
// เฉพาะผู้ใช้ที่ผ่านการยืนยันตัวตนเท่านั้นที่สามารถเขียน
".write": "auth !== null",
".indexOn": ["timestamp"]
}
}
}
กฎยังรองรับการทำดัชนีข้อมูลผ่านคำสั่ง ".indexOn" หากไม่มี คำสั่งที่มีการเรียงลำดับ (orderByChild) จะถูกปฏิเสธหรือทำงานอย่างไม่มีประสิทธิภาพ ดัชนีจะถูกระบุสำหรับแต่ละเส้นทางที่มีการเรียงลำดับตามฟิลด์เฉพาะ กฎเป็นแบบลดหลั่น: กฎที่ลึกกว่าจะแทนที่กฎแม่ และหากไม่มีการกำหนดการเข้าถึงในระดับใด จะถือว่าอนุญาตหรือปฏิเสธขึ้นอยู่กับกฎแม่
Realtime Database รองรับข้อมูลห้าประเภท: String, Number, Boolean, Map (ออบเจกต์) และ List (อาร์เรย์) ความลึกของการซ้อนกันถูกจำกัดที่ 32 ระดับ และขนาดสูงสุดของหนึ่งโหนดต้องไม่เกิน 256 MB สำหรับการทำงานกับฐานข้อมูลอย่างมีประสิทธิภาพ แนะนำให้ออกแบบโครงสร้างข้อมูลแบบแบนและใช้ Denormalization เพื่อหลีกเลี่ยงคำสั่งที่ลึกซึ่งโหลดข้อมูลปริมาณมาก
มาดูตัวอย่างการใช้งานจริงของการผสานรวม Realtime Database ในแอปพลิเคชัน Android สำหรับสถานะผู้ใช้ (ออนไลน์/ออฟไลน์) แอปพลิเคชันจะแสดงรายชื่อผู้ใช้พร้อมสถานะปัจจุบันของพวกเขา ซึ่งอัปเดตแบบเวลาจริง สำหรับการสาธิต ใช้ Firebase Authentication สำหรับการระบุตัวตนผู้ใช้และ coroutines สำหรับการดำเนินการแบบอะซิงโครนัส
ในการเริ่มต้น ให้เพิ่มการพึ่งพา firebase-database-ktx ในไฟล์ build.gradle ของโมดูลแอปพลิเคชัน เวอร์ชันไลบรารีถูกจัดการผ่าน Firebase BoM เพื่อให้แน่ใจว่าส่วนประกอบทั้งหมดทำงานร่วมกันได้ หลังจากเพิ่มการพึ่งพาแล้ว ต้องเริ่มต้น Firebase ในคลาส Application หรือผ่านการเริ่มต้นแบบ Lazy ใน ViewModel
dependencies {
implementation platform("com.google.firebase:firebase-bom:33.0.0")
implementation "com.google.firebase:firebase-database-ktx"
implementation "com.google.firebase:firebase-auth-ktx"
}
หลังจากการกำหนดค่า จะสร้าง repository สำหรับทำงานกับผู้ใช้ ผู้ใช้แต่ละคนจะแสดงด้วยโหนดในต้นไม้ /users/{uid} ที่มีฟิลด์ name, email และ status สำหรับการติดตามสถานะ ใช้ onDisconnect — กลไกพิเศษของ Firebase ที่ดำเนินการเขียนโดยอัตโนมัติเมื่อการเชื่อมต่อของไคลเอ็นต์ถูกขัดจังหวะ ซึ่งรับประกันว่าสถานะของผู้ใช้จะเปลี่ยนเป็น "offline" เมื่อปิดแอปพลิเคชันหรือสูญเสียเครือข่ายโดยไม่ต้องมีโค้ดเพิ่มเติมบนฝั่งไคลเอ็นต์
class PresenceRepository {
private val database = FirebaseDatabase.getInstance()
private val auth = FirebaseAuth.getInstance()
private val presenceRef = database
.getReference("presence")
fun trackPresence() {
val uid = auth.currentUser?.uid ?: return
val userRef = presenceRef.child(uid)
userRef.onDisconnect().setValue("offline")
userRef.setValue("online")
}
fun getPresenceStream(): Flow<Map<String, String>> =
presenceRef.snapshotFlow()
.map { snapshot ->
(snapshot.value as? Map<*, *>)
?.mapKeys { it.key.toString() }
?.mapValues { it.value.toString() }
?: emptyMap()
}
}
องค์ประกอบสำคัญของตัวอย่างคือ onDisconnect กลไกนี้ช่วยให้กำหนดการดำเนินการเขียนที่จะดำเนินการบนเซิร์ฟเวอร์เมื่อการเชื่อมต่อของไคลเอ็นต์ถูกขัดจังหวะ ในกรณีนี้ เมื่อผู้ใช้ตัดการเชื่อมต่อ สถานะของพวกเขาจะถูกตั้งเป็น "offline" โดยอัตโนมัติโดยไม่ต้องจัดการกับเหตุการณ์การปิดแอปพลิเคชัน หากแอปพลิเคชันสิ้นสุดอย่างผิดปกติ Firebase จะดำเนินการ onDisconnect เอง และผู้ใช้รายอื่นจะเห็นสถานะที่ถูกต้อง
คำถามที่พบบ่อย
Realtime Database เก็บข้อมูลในต้นไม้ JSON เดียวและให้ความหน่วงในการซิงโครไนซ์ที่ต่ำกว่า Firestore ใช้คอลเล็กชันเอกสาร รองรับคำสั่งที่ซับซ้อนและความสอดคล้องที่แข็งแกร่ง Realtime Database เหมาะสำหรับแชทและสถานะที่เรียบง่าย Firestore เหมาะสำหรับแอปพลิเคชันที่มีโครงสร้างข้อมูลที่ซับซ้อนและการวิเคราะห์
ขนาดสูงสุดของหนึ่งโหนด Realtime Database คือ 256 MB ความลึกของการซ้อนกันถูกจำกัดที่ 32 ระดับ สำหรับหนึ่งโครงการ Firebase สามารถสร้างฐานข้อมูล Realtime Database ได้หลายฐาน (สูงสุด 5 บนแผน Spark และสูงสุด 100 บนแผน Blaze) ซึ่งช่วยให้กระจายข้อมูลระหว่างอินสแตนซ์ต่างๆ ได้
Realtime Database ผสานรวมกับ Firebase Authentication ในกฎความปลอดภัยมีตัวแปร auth ที่มี uid ของผู้ใช้ที่ผ่านการยืนยันตัวตน นักพัฒนาสามารถจำกัดการเข้าถึงในระดับโหนดแต่ละโหนดของต้นไม้ JSON โดยตรวจสอบ uid ของเจ้าของข้อมูล ผู้ใช้ที่ไม่เปิดเผยตัวตนและไม่ผ่านการยืนยันตัวตนมี auth = null
ใช่ Realtime Database รองรับ ธุรกรรม ผ่านเมธอด runTransaction ธุรกรรมรับประกันความเป็นอะตอมของการดำเนินการอ่าน-แก้ไข-เขียนสำหรับหนึ่งโหนด เมื่อมีการเปลี่ยนแปลงพร้อมกัน ธุรกรรมจะถูกทำซ้ำด้วยข้อมูลปัจจุบัน ซึ่งมีประโยชน์สำหรับตัวนับ การให้คะแนน และสถานการณ์อื่นๆ ที่ความสอดคล้องของข้อมูลมีความสำคัญ
ใช่ Realtime Database รองรับโหมดออฟไลน์บน Android และ iOS SDK แคชข้อมูลในเครื่องและดำเนินการเขียนต่อไปเมื่อไม่มีเครือข่าย เมื่อกู้คืนการเชื่อมต่อ การเปลี่ยนแปลงที่สะสมทั้งหมดจะถูกซิงโครไนซ์กับเซิร์ฟเวอร์ สำหรับการเปิดโหมดออฟไลน์ ใช้เมธอด keepSynced(true) บนโหนดที่ต้องการ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม