0Pricing
Android Academy · บทเรียน

พื้นฐาน Cloud Firestore

อ่านและเขียนข้อมูลแบบเรียลไทม์

พื้นฐาน Cloud Firestore เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 4 บทเรียน

Cloud Firestore คืออะไร

Cloud Firestore คือฐานข้อมูล NoSQL ของ Firebase ที่ยืดหยุ่นและปรับขนาดได้ โดยจัดเก็บข้อมูลเป็น เอกสาร ซึ่งจัดกลุ่มอยู่ใน คอลเลกชัน

  • เอกสาร คือชุดฟิลด์คีย์/ค่า (คล้ายออบเจ็กต์ JSON)
  • คอลเลกชัน คือภาชนะที่เก็บเอกสาร
  • เอกสารสามารถมี คอลเลกชันย่อย ทำให้เกิดโครงสร้างแบบต้นไม้

Firestore ยังรองรับ การอัปเดตแบบเรียลไทม์ และทำงานแบบ ออฟไลน์ ได้ทันทีโดยไม่ต้องตั้งค่าเพิ่มเติม

รับอินสแตนซ์ Firestore

เข้าถึงฐานข้อมูลผ่าน Firebase.firestore จากนั้นเข้าถึงคอลเลกชันด้วย collection("name") และเข้าถึงเอกสารเฉพาะรายการด้วย document("id")

การสร้างข้อมูลอ้างอิงใช้ทรัพยากรน้อย เพราะข้อมูลอ้างอิงเหล่านี้อธิบายเพียง ตำแหน่ง ไม่ใช่ตัวข้อมูลเอง

import com.google.firebase.Firebase
import com.google.firebase.firestore.firestore

val db = Firebase.firestore

val usersRef = db.collection("users")
val oneUser = db.collection("users").document("abc123")

ออกแบบโครงสร้างข้อมูล

Firestore จับคู่กับ คลาสข้อมูล ของ Kotlin ได้อย่างลงตัว พร็อพเพอร์ตีแต่ละรายการจะกลายเป็นฟิลด์ในเอกสาร

กำหนดให้มี ตัวสร้างที่ไม่มีอาร์กิวเมนต์ (ค่าปริยายจะจัดการเรื่องนี้ให้) เพื่อให้ Firestore แปลงเอกสารกลับเป็นออบเจ็กต์ได้

data class Note(
    val title: String = "",
    val body: String = "",
    val done: Boolean = false,
    val createdAt: Long = 0L
)

เขียนเอกสาร

ใช้ set เพื่อสร้างหรือเขียนทับเอกสาร ให้ Firestore สร้าง ID ด้วย add หรือเลือก ID เองด้วย document(id).set(...)

คำสั่งเหล่านี้ส่งคืน Task และเมื่อใช้โครูทีน คุณสามารถใช้ await() กับคำสั่งเหล่านี้ได้

import com.google.firebase.Firebase
import com.google.firebase.firestore.firestore
import kotlinx.coroutines.tasks.await

suspend fun addNote(note: Note): String {
    val ref = Firebase.firestore
        .collection("notes")
        .add(note)          // auto-generated ID
        .await()
    return ref.id
}

อ่านเอกสาร

get() จะดึงเอกสารหนึ่งครั้ง แปลงเอกสารนั้นเป็นคลาสข้อมูลของคุณด้วย toObject(Note::class.java)

ตรวจสอบ exists() เสมอ เพราะการอ้างอิงเอกสารที่ไม่มีอยู่จะส่งคืนสแนปชอตที่ไม่มีเอกสารนั้นจริง

import com.google.firebase.Firebase
import com.google.firebase.firestore.firestore
import kotlinx.coroutines.tasks.await

suspend fun loadNote(id: String): Note? {
    val snapshot = Firebase.firestore
        .collection("notes")
        .document(id)
        .get()
        .await()
    return if (snapshot.exists()) snapshot.toObject(Note::class.java) else null
}

อัปเดตและลบ

update เปลี่ยนฟิลด์ที่ระบุโดยไม่กระทบส่วนที่เหลือของเอกสาร ส่วน delete จะลบเอกสารทั้งหมด

ใช้ set(..., SetOptions.merge()) หากต้องการเขียนข้อมูลเพียงบางส่วน และต้องการให้สร้างเอกสารด้วยเมื่อเอกสารนั้นยังไม่มี

import com.google.firebase.Firebase
import com.google.firebase.firestore.firestore
import kotlinx.coroutines.tasks.await

suspend fun markDone(id: String) {
    Firebase.firestore.collection("notes").document(id)
        .update("done", true)
        .await()
}

suspend fun removeNote(id: String) {
    Firebase.firestore.collection("notes").document(id)
        .delete()
        .await()
}

สืบค้นคอลเลกชัน

สร้างคำค้นด้วยการเชื่อมตัวกรองต่อกัน ได้แก่ whereEqualTo, whereGreaterThan, orderBy, limit และอื่น ๆ

คำค้นจะส่งคืน QuerySnapshot ให้ไล่ดูเอกสารในนั้นเพื่อแปลงแต่ละรายการเป็นโมเดลของคุณ

import com.google.firebase.Firebase
import com.google.firebase.firestore.firestore
import kotlinx.coroutines.tasks.await

suspend fun pendingNotes(): List<Note> {
    val snap = Firebase.firestore.collection("notes")
        .whereEqualTo("done", false)
        .orderBy("createdAt")
        .limit(20)
        .get()
        .await()
    return snap.documents.mapNotNull { it.toObject(Note::class.java) }
}

ตัวติดตามแบบเรียลไทม์

จุดเด่นของ Firestore คือการทำงานแบบ เรียลไทม์ addSnapshotListener จะส่งข้อมูลปัจจุบันให้ทันที จากนั้นส่งการเปลี่ยนแปลงทุกครั้งโดยอัตโนมัติ

คำสั่งนี้ส่งคืน ListenerRegistration ให้เรียก remove() เมื่อใช้งานเสร็จเพื่อหยุดรับการอัปเดต

import com.google.firebase.Firebase
import com.google.firebase.firestore.firestore

val registration = Firebase.firestore.collection("notes")
    .whereEqualTo("done", false)
    .addSnapshotListener { snapshot, error ->
        if (error != null || snapshot == null) return@addSnapshotListener
        val notes = snapshot.toObjects(Note::class.java)
        println("Now have ${notes.size} pending notes")
    }

// Later: registration.remove()

ข้อมูลเรียลไทม์ในรูปแบบ Flow

ใน Compose แนวทางมาตรฐานคือเปิดเผยข้อมูล Firestore เป็น Kotlin Flow โดย callbackFlow จะเชื่อมการเรียกกลับของตัวติดตามเข้ากับโฟลว์ และ awaitClose จะลบตัวติดตามเมื่อหยุดรวบรวมข้อมูล

import com.google.firebase.Firebase
import com.google.firebase.firestore.firestore
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow

fun notesFlow(): Flow<List<Note>> = callbackFlow {
    val reg = Firebase.firestore.collection("notes")
        .addSnapshotListener { snap, err ->
            if (err == null && snap != null) {
                trySend(snap.toObjects(Note::class.java))
            }
        }
    awaitClose { reg.remove() }
}

แสดงข้อมูลใน Compose

รวบรวมโฟลว์ด้วย collectAsStateWithLifecycle() แล้วแสดงผลใน LazyColumn รายการจะอัปเดตตัวเองทุกครั้งที่ Firestore เปลี่ยนแปลง — ไม่ต้องรีเฟรชด้วยตนเอง

@Composable
fun NotesScreen(viewModel: NotesViewModel) {
    val notes by viewModel.notes.collectAsStateWithLifecycle()

    LazyColumn {
        items(notes) { note ->
            ListItem(
                headlineContent = { Text(note.title) },
                supportingContent = { Text(note.body) }
            )
        }
    }
}

กฎความปลอดภัยมีความสำคัญ

โดยค่าเริ่มต้น Firestore จะถูกล็อกไว้ กฎความปลอดภัย เป็นตัวกำหนดว่าใครอ่านหรือเขียนแต่ละเส้นทางได้บ้าง กฎเหล่านี้ทำงานบนเซิร์ฟเวอร์และไคลเอ็นต์ไม่สามารถข้ามได้

กฎที่ใช้บ่อยคือ ผู้ใช้จะเข้าถึงได้เฉพาะข้อมูลของตนเอง โดยใช้ uid ของการยืนยันตัวตนเป็นคีย์

// firestore.rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId}/{document=**} {
      allow read, write: if request.auth != null
                         && request.auth.uid == userId;
    }
  }
}

ตรวจสอบความเข้าใจ

คุณต้องการรายการ Compose ที่อัปเดตทันทีเมื่อข้อมูล Firestore ต้นทางเปลี่ยนแปลง โดยไม่ต้องรีเฟรชด้วยตนเอง คุณควรใช้ API ใด

สรุป: Firestore

ตอนนี้คุณสามารถจัดเก็บและซิงค์ข้อมูลด้วย Cloud Firestore ได้แล้ว:

  • ข้อมูลจะอยู่ในรูปของ เอกสารภายใน คอลเลกชัน และสร้างโมเดลด้วยคลาสข้อมูลของ Kotlin
  • เขียนด้วย add/set อ่านด้วย get และเปลี่ยนแปลงด้วย update/delete
  • สืบค้นด้วย whereEqualTo, orderBy, limit
  • ใช้ addSnapshotListener (หรือ callbackFlow) สำหรับ UI แบบ เรียลไทม์
  • ปกป้องข้อมูลด้วย กฎความปลอดภัย ที่ใช้ request.auth.uid เป็นคีย์

ถัดไป: ติดต่อผู้ใช้เมื่อแอปปิดอยู่ด้วย Cloud Messaging

คำถามที่พบบ่อย

บทเรียน “พื้นฐาน Cloud Firestore” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “พื้นฐาน Cloud Firestore” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “พื้นฐาน Cloud Firestore”

อ่านและเขียนข้อมูลแบบเรียลไทม์ คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “พื้นฐาน Cloud Firestore” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม

ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การตั้งค่า Firebase
  2. การยืนยันตัวตนด้วย Firebase
  3. พื้นฐาน Cloud Firestore
  4. การพุชด้วย Cloud Messaging
← กลับไปที่ Android Academy