Podstawy Cloud Firestore
Odczytuj i zapisuj dane w czasie rzeczywistym
Podstawy Cloud Firestore to bezpłatna lekcja Android Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Android Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Android Academy zawiera 4 lekcji w sumie.
Czym jest Cloud Firestore?
Cloud Firestore to elastyczna i skalowalna baza danych NoSQL firmy Firebase. Przechowuje dane w postaci dokumentów pogrupowanych w kolekcje.
- Dokument to zbiór pól klucz/wartość (podobnie jak obiekt JSON).
- Kolekcja to kontener na dokumenty.
- Dokumenty mogą zawierać podkolekcje, tworząc strukturę drzewa.
Firestore oferuje także aktualizacje w czasie rzeczywistym i domyślnie działa offline.
Pobieranie instancji Firestore
Uzyskaj dostęp do bazy danych za pomocą Firebase.firestore. Następnie uzyskaj dostęp do kolekcji przez collection("name"), a do konkretnego dokumentu przez document("id").
Tworzenie odwołań jest niedrogie — opisują one lokalizację, a nie same dane.
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")Modelowanie danych
Firestore dobrze współpracuje z kotlinowymi klasami danych. Każda właściwość staje się polem dokumentu.
Dodaj konstruktor bezargumentowy (wartości domyślne spełniają ten warunek), aby Firestore mógł deserializować dokumenty z powrotem do obiektów.
data class Note(
val title: String = "",
val body: String = "",
val done: Boolean = false,
val createdAt: Long = 0L
)Zapisywanie dokumentu
Użyj set, aby utworzyć dokument lub zastąpić jego zawartość. Pozwól Firestore wygenerować identyfikator za pomocą add albo wybierz własny identyfikator za pomocą document(id).set(...).
Te wywołania zwracają obiekty Task; w korutynach można użyć na nich 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
}Odczytywanie dokumentu
get() jednorazowo pobiera dokument. Przekształć go w klasę danych za pomocą toObject(Note::class.java).
Zawsze sprawdzaj exists() — odwołanie do nieistniejącego dokumentu zwraca migawkę, która po prostu nie istnieje.
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
}Aktualizowanie i usuwanie
update zmienia określone pola bez modyfikowania pozostałej części dokumentu. delete całkowicie usuwa dokument.
Użyj set(..., SetOptions.merge()), jeśli chcesz wykonać częściowy zapis, który jednocześnie utworzy dokument, gdy go brakuje.
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()
}Wykonywanie zapytań do kolekcji
Twórz zapytania, łącząc filtry: whereEqualTo, whereGreaterThan, orderBy, limit i inne.
Zapytanie zwraca obiekt QuerySnapshot; przeiteruj po jego dokumentach, aby przekształcić każdy z nich w model.
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) }
}Listenery czasu rzeczywistego
Największą zaletą Firestore jest działanie w czasie rzeczywistym. addSnapshotListener natychmiast dostarcza bieżące dane, a następnie automatycznie przekazuje każdą zmianę.
Zwraca obiekt ListenerRegistration — po zakończeniu wywołaj remove(), aby zatrzymać odbieranie aktualizacji.
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()Dane czasu rzeczywistego jako Flow
W Compose standardowym podejściem jest udostępnienie danych Firestore jako kotlinowego obiektu Flow. callbackFlow łączy wywołanie zwrotne listenera z przepływem, a awaitClose usuwa listener po zatrzymaniu zbierania danych.
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() }
}Wyświetlanie danych w Compose
Zbieraj dane z przepływu za pomocą collectAsStateWithLifecycle() i wyświetlaj je w LazyColumn. Lista aktualizuje się automatycznie za każdym razem, gdy dane Firestore ulegną zmianie — bez ręcznego odświeżania.
@Composable
fun NotesScreen(viewModel: NotesViewModel) {
val notes by viewModel.notes.collectAsStateWithLifecycle()
LazyColumn {
items(notes) { note ->
ListItem(
headlineContent = { Text(note.title) },
supportingContent = { Text(note.body) }
)
}
}
}Reguły bezpieczeństwa mają znaczenie
Domyślnie Firestore jest zablokowany. Reguły bezpieczeństwa określają, kto może odczytywać poszczególne ścieżki i zapisywać w nich dane — są wykonywane na serwerze i nie można ich ominąć po stronie klienta.
Typowa reguła mówi, że użytkownik może uzyskiwać dostęp wyłącznie do własnych danych, identyfikowanych przez jego uwierzytelniony 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;
}
}
}Szybkie sprawdzenie
Chcesz utworzyć listę Compose, która natychmiast aktualizuje się po każdej zmianie bazowych danych Firestore, bez ręcznego odświeżania. Z którego interfejsu API należy skorzystać?
Podsumowanie: Firestore
Potrafisz już przechowywać i synchronizować dane za pomocą Cloud Firestore:
- Dane są przechowywane jako dokumenty w kolekcjach; modeluj je za pomocą kotlinowych klas danych.
- Zapisuj je za pomocą
add/set, odczytuj za pomocąget, a zmieniaj i usuwaj za pomocąupdate/delete. - Wykonuj zapytania za pomocą
whereEqualTo,orderByilimit. - Używaj
addSnapshotListener(lubcallbackFlow) do tworzenia interfejsu reagującego w czasie rzeczywistym. - Chroń dane za pomocą reguł bezpieczeństwa opartych na
request.auth.uid.
Dalej: docieranie do użytkowników, gdy aplikacja jest zamknięta, za pomocą Cloud Messaging.
Często zadawane pytania
Czy lekcja „Podstawy Cloud Firestore” jest bezpłatna?
Tak — pełny tekst „Podstawy Cloud Firestore” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Android Academy, przejdź na CoddyKit PRO. Kurs Android Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Podstawy Cloud Firestore”?
Odczytuj i zapisuj dane w czasie rzeczywistym Ćwiczysz Android Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Android Academy?
Nie wymagamy żadnego doświadczenia. Android Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Podstawy Cloud Firestore”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Android Academy?
Tak. Każda lekcja Android Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Konfiguracja Firebase
- Uwierzytelnianie Firebase
- Podstawy Cloud Firestore
- Wysyłanie za pomocą Cloud Messaging