Cloud Firestore 기초
실시간 데이터를 읽고 씁니다.
Cloud Firestore 기초은(는) CoddyKit의 무료 Android Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Android Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
Cloud Firestore란 무엇인가요?
Cloud Firestore는 유연하고 확장 가능한 Firebase의 NoSQL 데이터베이스입니다. 데이터는 문서로 저장되며, 문서는 컬렉션으로 그룹화됩니다.
- 문서는 키/값 필드의 집합입니다(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을 사용해 문서를 만들거나 덮어씁니다. add를 사용하면 Firestore가 ID를 생성하고, document(id).set(...)을 사용하면 직접 ID를 지정할 수 있습니다.
이 호출들은 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는 리스너 콜백을 flow로 연결하고, 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()로 flow를 수집하고 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;
}
}
}빠른 확인
기반이 되는 Firestore 데이터가 변경될 때마다 수동으로 새로 고치지 않아도 즉시 업데이트되는 Compose 목록을 만들려고 합니다. 어떤 API를 사용해야 할까요?
복습: Firestore
이제 Cloud Firestore로 데이터를 저장하고 동기화할 수 있습니다.
- 데이터는 컬렉션 안의 문서로 저장하며 Kotlin 데이터 클래스로 모델링합니다.
add/set으로 쓰고,get으로 읽으며,update/delete로 변경합니다.whereEqualTo,orderBy,limit으로 쿼리합니다.- 실시간 UI에는
addSnapshotListener(또는callbackFlow)를 사용합니다. request.auth.uid를 기준으로 하는 보안 규칙으로 데이터를 보호합니다.
다음 주제: 앱이 닫혀 있을 때도 Cloud Messaging으로 사용자에게 도달하기
자주 묻는 질문
“Cloud Firestore 기초” 강의는 무료인가요?
네 — “Cloud Firestore 기초” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Android Academy 강의 전체를 잠금 해제할 수 있습니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“Cloud Firestore 기초”에서 뭘 배우나요?
실시간 데이터를 읽고 씁니다. 브라우저에서 직접 실행하는 실습 코드로 Android Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Android Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Android Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“Cloud Firestore 기초” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Android Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Android Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- Firebase 설정
- Firebase 인증
- Cloud Firestore 기초
- Cloud Messaging으로 푸시 알림 보내기