Firebase Firestore คือฐานข้อมูล NoSQL บนคลาวด์แบบเรียลไทม์จาก Google ที่ออกแบบมาสำหรับแอปพลิเคชันมือถือและเว็บ มันจัดเก็บข้อมูลในรูปแบบคอลเลกชันและเอกสารพร้อมการซิงโครไนซ์อัตโนมัติระหว่างไคลเอนต์ ตามเอกสาร Firebase, 2025 Firestore รองรับการปรับใช้หลายภูมิภาคด้วยความสอดคล้องที่เข้มแข็งและให้การปรับขนาดอัตโนมัติโดยไม่ต้องจัดการเซิร์ฟเวอร์ ฐานข้อมูลสามารถทำงานร่วมกับ Firebase Authentication และ Cloud Functions เพื่อสร้างแบ็กเอนด์ที่สมบูรณ์โดยไม่มีโครงสร้างพื้นฐานเซิร์ฟเวอร์ของตัวเอง
ประเด็นสำคัญ
Firebase Firestore คือฐานข้อมูล NoSQL ที่ยืดหยุ่นและปรับขนาดได้ เปิดตัวโดย Google ในปี 2019 เพื่อเป็นวิวัฒนาการของ Firebase Realtime Database มันจัดเก็บข้อมูลในคอลเลกชันของเอกสาร โดยแต่ละเอกสารประกอบด้วยชุดคู่คีย์-ค่า แตกต่างจากฐานข้อมูลเชิงสัมพันธ์แบบดั้งเดิม Firestore ไม่ต้องการสคีมาที่กำหนดไว้ล่วงหน้า — โครงสร้างข้อมูลถูกสร้างขึ้นแบบไดนามิกตามเอกสารที่เขียน
ความแตกต่างหลักระหว่าง Firestore และฐานข้อมูลบนคลาวด์แบบคลาสสิกคือการซิงโครไนซ์แบบเรียลไทม์ในตัว เมื่อข้อมูลเปลี่ยนแปลงบนเซิร์ฟเวอร์ ไคลเอนต์ที่เชื่อมต่อทั้งหมดจะได้รับการอัปเดตผ่านการเชื่อมต่อ WebSocket ถาวร ซึ่งช่วยลดความจำเป็นในการสอบถามเซิร์ฟเวอร์ด้วยตนเองและช่วยให้สร้างแอปพลิเคชันที่มีการอัปเดตสดได้ เช่น แชท ฟีดกิจกรรม ตัวแก้ไขร่วมกัน และระบบตรวจสอบ
ฐานข้อมูลพร้อมใช้งานบนแพลตฟอร์มหลักทั้งหมด: Android, iOS, Web (JavaScript) และภาษาเซิร์ฟเวอร์ผ่าน Admin SDK Firestore มี SDK สำหรับ Swift, Kotlin, JavaScript, Python, Go, Java และ Node.js ตามข้อมูลของ Google Firestore ประมวลผลคำขอมากกว่า 100 พันล้านครั้งต่อวันทั่วทั้งระบบนิเวศของ Firebase ซึ่งยืนยันความน่าเชื่อถือในฐานะรากฐานสำหรับแอปพลิเคชันในระดับการผลิต
ใน Firestore ข้อมูลถูกจัดระเบียบในโครงสร้างแบบลำดับชั้น คอลเลกชันคือคอนเทนเนอร์ของเอกสาร คล้ายกับตารางใน SQL แต่ไม่มีสคีมาตายตัว เอกสารคือเรกคอร์ดที่ประกอบด้วยฟิลด์ประเภทต่าง ๆ: สตริง ตัวเลข ค่าบูลีน อาร์เรย์ วัตถุซ้อน และจุดพิกัดทางภูมิศาสตร์ เอกสารสามารถมีคอลเลกชันย่อย ซึ่งช่วยให้สร้างโครงสร้างข้อมูลซ้อนกันในระดับความลึกใดก็ได้
val db = FirebaseFirestore.getInstance()
val user = hashMapOf(
"name" to "Anna Petrova",
"email" to "anna@example.com",
"age" to 28,
"isActive" to true
)
db.collection("users")
.add(user)
.addOnSuccessListener { docRef ->
Log.d("TAG", "เพิ่มเอกสารด้วย ID: ${docRef.id}")
}
แต่ละเอกสารในคอลเลกชันมีตัวระบุเฉพาะ ซึ่งสามารถสร้างขึ้นโดยอัตโนมัติหรือตั้งค่าด้วยตนเอง Firestore จะทำดัชนีฟิลด์เอกสารทั้งหมดโดยอัตโนมัติ ช่วยให้ค้นหาที่ซับซ้อนด้วยการกรอง การเรียงลำดับ และการจำกัดผลลัพธ์โดยไม่ต้องกำหนดค่าดัชนีด้วยตนเอง
Firestore และ Firebase Realtime Database เป็นฐานข้อมูลบนคลาวด์แบบเรียลไทม์สองตัวจาก Google แม้ว่าทั้งสองจะให้การซิงโครไนซ์แบบเรียลไทม์ แต่มีความแตกต่างพื้นฐานในโมเดลข้อมูล การปรับขนาด และการกำหนดราคา การทำความเข้าใจความแตกต่างเหล่านี้มีความสำคัญอย่างยิ่งในการเลือกฐานข้อมูลที่เหมาะสมสำหรับโครงการใดโครงการหนึ่ง
| คุณลักษณะ | Firestore | Realtime Database |
|---|---|---|
| โมเดลข้อมูล | คอลเลกชันและเอกสาร | ต้นไม้ JSON เดียว |
| ความสอดคล้อง | ความสอดคล้องที่เข้มแข็ง | ความสอดคล้องในที่สุด |
| คำสั่งค้นหา | แบบประกอบด้วยการกรองและการเรียงลำดับ | กรองด้วยพารามิเตอร์เดียวเท่านั้น |
| การปรับขนาด | อัตโนมัติ หลายภูมิภาค | ภูมิภาคเดียว สูงสุด 200k การเชื่อมต่อ |
| การกำหนดราคา | ต่อการดำเนินการอ่าน/เขียน/ลบ | ตามปริมาณข้อมูลที่ถ่ายโอน |
ความแตกต่างทางสถาปัตยกรรมหลักคือโมเดลข้อมูล Realtime Database จัดเก็บทุกอย่างในต้นไม้ JSON ขนาดใหญ่เดียว ซึ่งทำให้คำสั่งค้นหาที่ซ้อนกันลึกซับซ้อน Firestore ใช้คอลเลกชันและเอกสาร ซึ่งช่วยให้ค้นหาที่ซับซ้อนด้วยเงื่อนไขหลายรายการ นอกจากนี้ Firestore ยังให้ความสอดคล้องของข้อมูลที่เข้มแข็ง: หลังจากเขียนสำเร็จ การอ่านทั้งหมดในภายหลังจะรับประกันว่าจะคืนข้อมูลล่าสุด
Firestore ปรับขนาดโดยอัตโนมัติเป็นล้านการเชื่อมต่อพร้อมกันด้วยสถาปัตยกรรมหลายภูมิภาค Realtime Database ถูกจำกัดในภูมิภาคเดียวและสูงสุด 200,000 การเชื่อมต่อพร้อมกัน สำหรับโครงการที่กำหนดเป้าหมายผู้ชมทั่วโลก Firestore เหมาะกว่าข้อมูลจะถูกทำซ้ำโดยอัตโนมัติระหว่างศูนย์ข้อมูลของ Google หลายแห่ง
โครงสร้างข้อมูลใน Firestore ช่วยให้สร้างโมเดลลำดับชั้นที่ซับซ้อนด้วยคอลเลกชันย่อย เช่น ผู้ใช้สามารถมีคอลเลกชันย่อย «คำสั่งซื้อ» และแต่ละคำสั่งซื้อมีคอลเลกชันย่อย «สินค้า» ใน Realtime Database การซ้อนลึกเช่นนี้ทำให้เกิดปัญหาด้านประสิทธิภาพระหว่างการค้นหา เนื่องจากต้องโหลดเส้นทางทั้งหมดจากรากไปยังโหนดที่ต้องการ
Firestore ใช้การเชื่อมต่อ WebSocket ถาวรระหว่างไคลเอนต์และเซิร์ฟเวอร์สำหรับการซิงโครไนซ์ข้อมูลแบบเรียลไทม์ เมื่อแอปพลิเคชันสมัครรับการเปลี่ยนแปลงในเอกสารหรือคอลเลกชันผ่าน snapshot listener SDK จะสร้างช่องทางการสื่อสารที่เซิร์ฟเวอร์ส่งการอัปเดตทุกครั้งที่ข้อมูลเปลี่ยนแปลง ไคลเอนต์ได้รับเฉพาะเอกสารที่เปลี่ยนแปลง ไม่ใช่ภาพรวมทั้งหมดของคอลเลกชันในทุกครั้ง
กลไกการซิงโครไนซ์ขึ้นอยู่กับสตรีมเหตุการณ์: added (เอกสารปรากฏ), modified (เอกสารเปลี่ยนแปลง) และ removed (เอกสถูกลบ) นักพัฒนาสามารถจัดการแต่ละเหตุการณ์แยกกัน โดยอัปเดตเฉพาะองค์ประกอบ UI ที่เกี่ยวข้องเท่านั้น ซึ่งรับประกันประสิทธิภาพสูงแม้มีเอกสารเป็นพัน เนื่องจากเฉพาะส่วนประกอบที่เปลี่ยนแปลงเท่านั้นที่ถูกเรนเดอร์ใหม่
ข้อดีหลักอย่างหนึ่งของ Firestore คือการรองรับโหมดออฟไลน์ในตัว SDK จะแคชข้อมูลที่อ่านทั้งหมดบนอุปกรณ์โดยอัตโนมัติและทำงานต่อไปเมื่อไม่มีเครือข่าย เมื่อแอปพลิเคชันเขียนข้อมูลในโหมดออฟไลน์ ข้อมูลจะถูกวางในคิวท้องถิ่นและส่งไปยังเซิร์ฟเวอร์เมื่อเชื่อมต่ออีกครั้ง กลยุทธ์ last-write-wins ใช้สำหรับการแก้ไขข้อขัดแย้ง
val docRef = db.collection("cities").document("SF")
docRef.addSnapshotListener { snapshot, error ->
if (error != null) {
Log.w("TAG", "ข้อผิดพลาดในการฟัง", error)
return@addSnapshotListener
}
if (snapshot != null && snapshot.exists()) {
Log.d("TAG", "ข้อมูลปัจจุบัน: ${snapshot.data}")
}
}
ขนาดแคชสามารถกำหนดค่าได้ผ่าน FirestoreSettings ค่าเริ่มต้นคือ 100 MB แต่สามารถเพิ่มสำหรับแอปพลิเคชันที่อ่านข้อมูลมาก นอกจากนี้ยังมีโหมดแคชดิสก์ถาวรที่คงอยู่แม้หลังจากรีสตาร์ทแอปพลิเคชัน เพื่อจัดการความพร้อมใช้งานของโหมดออฟไลน์ ใช้เมธอด enableNetwork และ disableNetwork ซึ่งช่วยให้ปิดการโต้ตอบเครือข่ายชั่วคราว
Firestore Security Rules คือภาษามาร์กอัปแบบประกาศสำหรับควบคุมการเข้าถึงข้อมูลในระดับเซิร์ฟเวอร์ กฎกำหนดว่าใครสามารถอ่านและเขียนเอกสารได้ภายใต้เงื่อนไขใด กฎทำงานก่อนการดำเนินการค้นหาและไม่ต้องการตรรกะเซิร์ฟเวอร์แยกต่างหากสำหรับการอนุญาต กฎจะถูกตรวจสอบฝั่ง Firebase ก่อนการอ่านหรือเขียนข้อมูลแต่ละครั้ง
กฎการเข้าถึงสร้างขึ้นบนหลักการอนุญาต (allow) โดยค่าเริ่มต้น การเข้าถึงทั้งหมดจะถูกปฏิเสธ นักพัฒนาเปิดการเข้าถึงตามลำดับสำหรับการดำเนินการเฉพาะ (read, write, create, update, delete) ภายใต้เงื่อนไขที่กำหนด เงื่อนไขสามารถตรวจสอบการรับรองความถูกต้องของผู้ใช้ผ่าน request.auth ข้อมูลคำขอผ่าน request.resource และข้อมูลที่มีอยู่ผ่าน resource
// กฎการเข้าถึง Firestore
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// ผู้ใช้อ่านและเขียนเฉพาะข้อมูลของตนเองเท่านั้น
match /users/{userId} {
allow read, write: if
request.auth != null &&
request.auth.uid == userId;
}
// ผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์สามารถอ่านโพสต์ได้
match /posts/{postId} {
allow read: if request.auth != null;
allow create: if request.auth != null
&& request.resource.data.author == request.auth.uid;
}
}
}
นอกเหนือจากการควบคุมการเข้าถึง Security Rules ยังช่วยให้ตรวจสอบโครงสร้างและประเภทของข้อมูลที่เขียนได้ เช่น สามารถตรวจสอบว่าฟิลด์อีเมลตรงกับนิพจน์ปกติ หรืออายุไม่เกิน 120 ปี การตรวจสอบจะดำเนินการก่อนการเขียน ซึ่งป้องกันการบันทึกข้อมูลที่ไม่ถูกต้องบนเซิร์ฟเวอร์ สำหรับการตรวจสอบฟิลด์ ใช้วัตถุ request.resource.data ที่มีเอกสารทั้งหมดที่กำลังเขียน
Firestore ยังรองรับคอลเลกชันที่เข้าถึงได้เฉพาะการเขียนฝั่งเซิร์ฟเวอร์ผ่าน Admin SDK โดยไม่มีการเข้าถึงจากไคลเอนต์ ซึ่งสะดวกสำหรับการจัดเก็บข้อมูลบริการ คีย์ API และการกำหนดค่าที่ไม่ควรปรากฏแก่ผู้ใช้ โดยในกฎก็เพียงพอที่จะปฏิเสธการดำเนินการของไคลเอนต์ทั้งหมดในคอลเลกชันที่เกี่ยวข้อง อนุญาตการเข้าถึงผ่าน Admin SDK จากฝั่งเซิร์ฟเวอร์เท่านั้น
มาดูตัวอย่างการรวม Firestore ในแอปพลิเคชัน Android เพื่อสร้างรายการสิ่งที่ต้องทำ (todo) แอปพลิเคชันจะอ่านงานแบบเรียลไทม์ เพิ่มงานใหม่ และทำเครื่องหมายงานที่เสร็จสมบูรณ์ สำหรับการทำงานแบบอะซิงโครนัส ใช้อินเทอร์เฟซ callback ของ Firebase และ coroutine ของ Kotlin
ก่อนเริ่มต้น จำเป็นต้องเชื่อมต่อโครงการกับ Firebase ผ่าน Firebase Console และเพิ่มไฟล์ google-services.json ในโมดูลแอปพลิเคชัน จากนั้นใน build.gradle เพิ่ม dependency firebase-firestore-ktx และปลั๊กอิน google-services เวอร์ชันของไลบรารีต้องตรงกับเวอร์ชัน BoM Firebase ปัจจุบันเพื่อความเข้ากันได้ของส่วนประกอบ Firebase ทั้งหมดระหว่างกัน
dependencies {
// Firebase BoM — การจัดการเวอร์ชัน
implementation platform("com.google.firebase:firebase-bom:33.0.0")
implementation "com.google.firebase:firebase-firestore-ktx"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.9.0"
}
หลังการตั้งค่า จะสร้างโมเดลข้อมูล Task และพื้นที่เก็บข้อมูล (repository) สำหรับทำงานกับ Firestore โมเดลประกอบด้วยฟิลด์ id, title, isCompleted และ timestamp Firestore จะทำ serialization ข้อมูลคลาสเป็นเอกสารโดยอัตโนมัติ โดยใช้ชื่อฟิลด์เป็นคีย์ สำหรับการอ่านข้อมูล ใช้ snapshot listener ที่คืนค่า Flow ผ่านส่วนขยาย snapshotFlow
data class Task(
val id: String = "",
val title: String = "",
val isCompleted: Boolean = false,
val createdAt: Timestamp? = null
)
class TaskRepository {
private val tasksRef = FirebaseFirestore
.getInstance()
.collection("tasks")
fun getTasks(): Flow<List<Task>> = tasksRef
.orderBy("createdAt", Query.Direction.DESCENDING)
.snapshotFlow()
.map { snapshot ->
snapshot?.toObjects(Task::class.java) ?: emptyList()
}
suspend fun addTask(title: String) {
tasksRef.add(Task(title = title))
}
}
ViewModel สมัครรับ Flow จากพื้นที่เก็บข้อมูลและส่งรายการงานไปยังระดับ UI เมื่อเพิ่มงานใหม่ ฟังก์ชัน suspend ของพื้นที่เก็บข้อมูลจะถูกเรียกผ่านขอบเขต coroutine Firestore ซิงโครไนซ์การเปลี่ยนแปลงระหว่างไคลเอนต์ทั้งหมดโดยอัตโนมัติ: หากผู้ใช้คนหนึ่งเพิ่มงาน คนอื่นจะเห็นแบบเรียลไทม์โดยไม่ต้องรีเฟรชหน้าจอ
คำถามที่พบบ่อย
Firestore คือฐานข้อมูล NoSQL ที่มีสคีมายืดหยุ่น ไม่มีตาราง และไม่มีคำสั่ง JOIN ข้อมูลถูกจัดเก็บในคอลเลกชันเอกสาร ไม่ใช่ในแถวตาราง แตกต่างจาก SQL ตรงที่ Firestore ไม่ต้องการสคีมาที่กำหนดไว้ล่วงหน้าและปรับขนาดโดยอัตโนมัติโดยไม่ต้องโยกย้าย แต่ไม่รองรับคำสั่งค้นหาเชิงธุรกรรมที่ซับซ้อนระหว่างคอลเลกชัน
Firestore มีขีดจำกัดฟรีที่ generous (แผน Spark): 50,000 การอ่าน 20,000 การเขียน และ 20,000 การลบต่อวัน เมื่อเกินจะใช้แผน Blaze แบบจ่ายตามการใช้งาน: $0.06 ต่อ 100,000 การอ่าน และ $0.18 ต่อ 100,000 การเขียน ราคาขึ้นอยู่กับภูมิภาคและปริมาณข้อมูลที่ถ่ายโอน
Firestore ใช้กลยุทธ์ last-write-wins สำหรับการแก้ไขข้อขัดแย้ง: การเขียนล่าสุดในเอกสารจะแทนที่ก่อนหน้าทั้งหมด สำหรับการควบคุมที่ละเอียดยิ่งขึ้น มี ธุรกรรม (การดำเนินการอ่าน-เขียนแบบอะตอม) และการเขียนแบบกลุ่ม ซึ่งรับประกันความสมบูรณ์เมื่อดำเนินการกับเอกสารหลายรายการ
ได้ Firestore รองรับการส่งออกและนำเข้าข้อมูลผ่าน Firebase Console หรือ gcloud CLI การส่งออกจะดำเนินการในรูปแบบ Cloud Firestore Export และบันทึกใน Google Cloud Storage ข้อมูลสามารถโยกย้ายระหว่าง Firebase โครงการหรือส่งออกเพื่อวิเคราะห์ใน BigQuery และเครื่องมืออื่น ๆ
Firestore ไม่มีการค้นหาข้อความแบบเต็มในตัว สำหรับงานนี้ Google แนะนำให้ทำงานร่วมกับ Algolia หรือ Meilisearch หรือใช้ Cloud Functions กับ Elasticsearch คำสั่งค้นหาในตัวของ Firestore รองรับเฉพาะการตรวจสอบความเท่ากัน ช่วง และการมีอยู่ของฟิลด์เท่านั้น โดยไม่มีการค้นหาสตริงย่อย
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม