Firebase Firestore là cơ sở dữ liệu NoSQL đám mây thời gian thực của Google, được thiết kế cho ứng dụng di động và web. Nó lưu trữ dữ liệu dưới dạng collection và document với đồng bộ tự động giữa các client. Theo tài liệu Firebase, 2025, Firestore hỗ trợ triển khai đa khu vực với tính nhất quán mạnh và cung cấp khả năng mở rộng tự động mà không cần quản lý máy chủ. Cơ sở dữ liệu tích hợp với Firebase Authentication và Cloud Functions để xây dựng backend hoàn chỉnh mà không cần hạ tầng máy chủ riêng.
Những điểm chính
Firebase Firestore là cơ sở dữ liệu NoSQL linh hoạt, có khả năng mở rộng được Google ra mắt vào năm 2019 như một sự phát triển của Firebase Realtime Database. Nó lưu trữ dữ liệu trong các collection document, nơi mỗi document chứa một tập hợp các cặp khóa-giá trị. Không giống như cơ sở dữ liệu quan hệ truyền thống, Firestore không yêu cầu lược đồ định nghĩa trước — cấu trúc dữ liệu được hình thành động dựa trên các document được ghi.
Sự khác biệt chính giữa Firestore và các cơ sở dữ liệu đám mây cổ điển là đồng bộ thời gian thực tích hợp. Khi dữ liệu thay đổi trên máy chủ, tất cả client được kết nối nhận được cập nhật qua kết nối WebSocket liên tục. Điều này loại bỏ nhu cầu thăm dò máy chủ thủ công và cho phép xây dựng các ứng dụng có cập nhật trực tiếp: trò chuyện, dòng hoạt động, trình chỉnh sửa cộng tác và hệ thống giám sát.
Cơ sở dữ liệu có sẵn trên tất cả các nền tảng chính: Android, iOS, Web (JavaScript) và ngôn ngữ máy chủ qua Admin SDK. Firestore cung cấp SDK cho Swift, Kotlin, JavaScript, Python, Go, Java và Node.js. Theo Google, Firestore xử lý hơn 100 tỷ yêu cầu mỗi ngày trên toàn bộ hệ sinh thái Firebase, xác nhận độ tin cậy của nó làm nền tảng cho các ứng dụng sản xuất.
Trong Firestore, dữ liệu được tổ chức theo cấu trúc phân cấp. Collection là một vùng chứa document, tương tự như bảng trong SQL nhưng không có lược đồ cố định. Document là một bản ghi chứa các trường thuộc nhiều loại: chuỗi, số, giá trị boolean, mảng, đối tượng lồng nhau và điểm địa lý. Document có thể chứa subcollection, cho phép xây dựng cấu trúc dữ liệu lồng nhau ở bất kỳ độ sâu nào.
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", "Document được thêm với ID: ${docRef.id}")
}
Mỗi document trong collection có một định danh duy nhất, có thể được tạo tự động hoặc đặt thủ công. Firestore tự động lập chỉ mục tất cả các trường document, cho phép truy vấn phức tạp với lọc, sắp xếp và giới hạn kết quả mà không cần cấu hình chỉ mục thủ công.
Firestore và Firebase Realtime Database là hai cơ sở dữ liệu đám mây thời gian thực của Google. Mặc dù cả hai đều cung cấp đồng bộ thời gian thực, chúng có sự khác biệt cơ bản về mô hình dữ liệu, mở rộng và định giá. Hiểu những khác biệt này rất quan trọng khi chọn cơ sở dữ liệu phù hợp cho một dự án cụ thể.
| Đặc điểm | Firestore | Realtime Database |
|---|---|---|
| Mô hình dữ liệu | Collection và document | Cây JSON đơn |
| Tính nhất quán | Nhất quán mạnh | Nhất quán cuối cùng |
| Truy vấn | Kết hợp với lọc và sắp xếp | Chỉ lọc theo một tham số |
| Mở rộng | Tự động, đa khu vực | Một khu vực, tối đa 200k kết nối |
| Định giá | Theo thao tác đọc/ghi/xóa | Theo khối lượng dữ liệu truyền |
Sự khác biệt kiến trúc chính là mô hình dữ liệu. Realtime Database lưu trữ mọi thứ trong một cây JSON lớn, làm phức tạp các truy vấn có lồng ghép sâu. Firestore sử dụng collection và document, cho phép truy vấn phức tạp với nhiều điều kiện. Ngoài ra, Firestore cung cấp tính nhất quán dữ liệu mạnh: sau khi ghi thành công, tất cả các lần đọc tiếp theo đảm bảo trả về dữ liệu mới nhất.
Firestore tự động mở rộng đến hàng triệu kết nối đồng thời nhờ kiến trúc đa khu vực. Realtime Database bị giới hạn ở một khu vực và tối đa 200.000 kết nối đồng thời. Đối với các dự án nhắm đến đối tượng toàn cầu, Firestore được ưu tiên hơn vì dữ liệu được tự động sao chép qua nhiều trung tâm dữ liệu Google.
Cấu trúc dữ liệu trong Firestore cho phép xây dựng các mô hình phân cấp phức tạp với subcollection. Ví dụ: người dùng có thể có subcollection "đơn hàng" và mỗi đơn hàng có subcollection "sản phẩm". Trong Realtime Database, việc lồng ghép sâu như vậy gây ra vấn đề hiệu suất khi truy vấn vì toàn bộ đường dẫn từ gốc đến nút cần thiết được tải.
Firestore sử dụng kết nối WebSocket liên tục giữa client và máy chủ để đồng bộ dữ liệu thời gian thực. Khi một ứng dụng đăng ký thay đổi trong document hoặc collection qua snapshot listener, SDK thiết lập kênh liên lạc qua đó máy chủ gửi cập nhật mỗi khi dữ liệu thay đổi. Client chỉ nhận được document đã thay đổi, không phải toàn bộ snapshot của collection mỗi lần.
Cơ chế đồng bộ dựa trên luồng sự kiện: added (document xuất hiện), modified (document thay đổi) và removed (document bị xóa). Nhà phát triển có thể xử lý từng sự kiện riêng biệt, chỉ cập nhật các phần tử UI tương ứng. Điều này đảm bảo hiệu suất cao ngay cả với hàng nghìn document vì chỉ các thành phần thay đổi mới được kết xuất lại.
Một trong những lợi thế chính của Firestore là hỗ trợ chế độ ngoại tuyến tích hợp. SDK tự động lưu đệm tất cả dữ liệu đã đọc trên thiết bị và tiếp tục hoạt động khi không có mạng. Khi ứng dụng ghi dữ liệu ở chế độ ngoại tuyến, dữ liệu được đặt vào hàng đợi cục bộ và gửi đến máy chủ khi kết nối được khôi phục. Chiến lược last-write-wins được sử dụng để giải quyết xung đột.
val docRef = db.collection("cities").document("SF")
docRef.addSnapshotListener { snapshot, error ->
if (error != null) {
Log.w("TAG", "Lỗi lắng nghe", error)
return@addSnapshotListener
}
if (snapshot != null && snapshot.exists()) {
Log.d("TAG", "Dữ liệu hiện tại: ${snapshot.data}")
}
}
Kích thước bộ nhớ đệm có thể được cấu hình qua FirestoreSettings. Giá trị mặc định là 100 MB nhưng có thể tăng lên cho các ứng dụng có đọc dữ liệu nhiều. Chế độ bộ nhớ đệm đĩa liên tục cũng có sẵn, tồn tại sau khi khởi động lại ứng dụng. Để quản lý khả năng sẵn sàng của chế độ ngoại tuyến, các phương thức enableNetwork và disableNetwork được sử dụng, cho phép tạm thời vô hiệu hóa tương tác mạng.
Firestore Security Rules là ngôn ngữ đánh dấu khai báo để kiểm soát truy cập dữ liệu ở cấp máy chủ. Các quy tắc xác định ai có thể đọc và ghi document cũng như trong điều kiện nào. Chúng hoạt động trước khi thực thi truy vấn và không yêu cầu logic máy chủ riêng cho việc ủy quyền. Các quy tắc được kiểm tra ở phía Firebase trước mỗi lần đọc hoặc ghi dữ liệu.
Các quy tắc truy cập được xây dựng trên nguyên tắc cho phép (allow). Theo mặc định, tất cả truy cập đều bị từ chối. Nhà phát triển mở tuần tự quyền truy cập cho các thao tác cụ thể (read, write, create, update, delete) theo các điều kiện nhất định. Các điều kiện có thể kiểm tra xác thực người dùng qua request.auth, dữ liệu yêu cầu qua request.resource và dữ liệu hiện có qua resource.
// Quy tắc truy cập Firestore
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Người dùng chỉ đọc và ghi dữ liệu của họ
match /users/{userId} {
allow read, write: if
request.auth != null &&
request.auth.uid == userId;
}
// Bất kỳ người dùng xác thực nào có thể đọc bài viết
match /posts/{postId} {
allow read: if request.auth != null;
allow create: if request.auth != null
&& request.resource.data.author == request.auth.uid;
}
}
}
Ngoài kiểm soát truy cập, Security Rules cho phép xác thực cấu trúc và loại dữ liệu được ghi. Ví dụ: có thể kiểm tra trường email có khớp với biểu thức chính quy hay không, hoặc tuổi không vượt quá 120 năm. Xác thực được thực hiện trước khi ghi, ngăn lưu dữ liệu không chính xác trên máy chủ. Để xác thực trường, đối tượng request.resource.data chứa toàn bộ document đang được ghi được sử dụng.
Firestore cũng hỗ trợ các collection chỉ có thể truy cập để ghi phía máy chủ qua Admin SDK, mà không có truy cập từ client. Điều này thuận tiện cho việc lưu trữ thông tin dịch vụ, khóa API và cấu hình không nên hiển thị cho người dùng. Để làm điều này, chỉ cần từ chối tất cả thao tác client trên các collection tương ứng trong quy tắc, chỉ cho phép truy cập qua Admin SDK từ phía máy chủ.
Hãy xem xét ví dụ tích hợp Firestore vào ứng dụng Android để tạo danh sách việc cần làm (todo). Ứng dụng sẽ đọc công việc theo thời gian thực, thêm công việc mới và đánh dấu công việc đã hoàn thành. Để làm việc bất đồng bộ, các giao diện callback Firebase và coroutine Kotlin được sử dụng.
Trước khi bắt đầu, cần kết nối dự án với Firebase qua Firebase Console và thêm tệp google-services.json vào module ứng dụng. Sau đó, trong build.gradle thêm phụ thuộc firebase-firestore-ktx và plugin google-services. Phiên bản thư viện phải tương ứng với phiên bản BoM Firebase hiện tại để tương thích giữa tất cả các thành phần Firebase với nhau.
dependencies {
// Firebase BoM — quản lý phiên bản
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"
}
Sau khi thiết lập, một mô hình dữ liệu Task và kho lưu trữ để làm việc với Firestore được tạo. Mô hình chứa các trường id, title, isCompleted và timestamp. Firestore tự động tuần tự hóa lớp dữ liệu thành document, sử dụng tên trường làm khóa. Để đọc dữ liệu, một snapshot listener được sử dụng, trả về Flow qua phần mở rộng 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 đăng ký Flow từ kho lưu trữ và chuyển danh sách công việc đến cấp UI. Khi một công việc mới được thêm, hàm suspend của kho lưu trữ được gọi qua phạm vi coroutine. Firestore tự động đồng bộ thay đổi giữa tất cả client: nếu một người dùng thêm công việc, những người khác thấy nó trong thời gian thực mà không cần làm mới màn hình.
Câu hỏi thường gặp
Firestore là cơ sở dữ liệu NoSQL với lược đồ linh hoạt, không có bảng và không có truy vấn JOIN. Dữ liệu được lưu trữ trong collection document, không phải hàng bảng. Không giống SQL, Firestore không yêu cầu lược đồ định nghĩa trước và tự động mở rộng mà không cần di chuyển, nhưng không hỗ trợ truy vấn giao dịch phức tạp giữa các collection.
Firestore có giới hạn miễn phí hào phóng (gói Spark): 50.000 lần đọc, 20.000 lần ghi và 20.000 lần xóa mỗi ngày. Sau khi vượt quá, gói Blaze với thanh toán theo mức sử dụng được áp dụng: $0,06 cho 100.000 lần đọc và $0,18 cho 100.000 lần ghi. Giá phụ thuộc vào khu vực và khối lượng dữ liệu truyền.
Firestore sử dụng chiến lược last-write-wins để giải quyết xung đột: lần ghi cuối cùng vào document thay thế hoàn toàn lần trước đó. Để kiểm soát chi tiết hơn, giao dịch (thao tác đọc-ghi nguyên tử) và ghi theo lô có sẵn, đảm bảo tính toàn vẹn khi thao tác trên nhiều document.
Có, Firestore hỗ trợ xuất và nhập dữ liệu qua Firebase Console hoặc gcloud CLI. Xuất được thực hiện ở định dạng Cloud Firestore Export và lưu vào Google Cloud Storage. Dữ liệu có thể được di chuyển giữa các dự án Firebase hoặc xuất để phân tích trong BigQuery và các công cụ khác.
Firestore không có tìm kiếm toàn văn bản tích hợp. Cho nhiệm vụ này, Google khuyến nghị tích hợp với Algolia hoặc Meilisearch, hoặc sử dụng Cloud Functions với Elasticsearch. Truy vấn tích hợp của Firestore chỉ hỗ trợ kiểm tra bằng nhau, phạm vi và sự tồn tại của trường mà không tìm kiếm theo chuỗi con.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm