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 "آنا پتروا",
"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 واحد |
| سازگاری | قوی (strong consistency) | سازگاری نهایی |
| پرسوجوها | ترکیبی با فیلتر و مرتبسازی | فقط فیلتر بر اساس یک پارامتر |
| مقیاسپذیری | خودکار، چندمنطقهای | یک منطقه، تا 200k اتصال |
| قیمتگذاری | بر اساس عملیات خواندن/نوشتن/حذف | بر اساس حجم دادههای منتقلشده |
تفاوت معماری اصلی مدل داده است. Realtime Database همه چیز را در یک درخت JSON بزرگ ذخیره میکند که پرسوجوهای با تودرتویی عمیق را دشوار میکند. Firestore از مجموعهها و اسناد استفاده میکند که امکان اجرای پرسوجوهای پیچیده با چندین شرط را فراهم میکند. علاوه بر این، Firestore سازگاری قوی داده را تضمین میکند: پس از نوشتن موفق، تمام خواندنهای بعدی دادههای بهروز را برمیگردانند.
Firestore به لطف معماری چندمنطقهای به طور خودکار تا میلیونها اتصال همزمان مقیاسپذیر است. Realtime Database به یک منطقه و حداکثر 200000 اتصال همزمان محدود است. برای پروژههایی که مخاطب جهانی برنامهریزی میکنند، Firestore ترجیح داده میشود زیرا دادهها به طور خودکار بین چندین مرکز داده Google تکرار میشوند.
ساختار داده در Firestore امکان ساخت مدلهای سلسلهمراتبی پیچیده با زیرمجموعهها را فراهم میکند. به عنوان مثال، یک کاربر میتواند زیرمجموعه «سفارشات» داشته باشد و هر سفارش زیرمجموعه «محصولات». در Realtime Database چنین تودرتویی عمیق منجر به مشکلات عملکرد در پرسوجوها میشود، زیرا کل مسیر از ریشه تا گره مورد نظر بارگذاری میشود.
Firestore از اتصال دائمی WebSocket بین کلاینت و سرور برای همگامسازی دادهها در زمان واقعی استفاده میکند. وقتی برنامه از طریق snapshot listener تغییرات سند یا مجموعه را دنبال میکند، SDK یک کانال ارتباطی برقرار میکند که از طریق آن سرور با هر تغییر داده بهروزرسانی ارسال میکند. کلاینت فقط اسناد تغییر یافته را دریافت میکند، نه کل مجموعه را هر بار.
مکانیسم همگامسازی بر اساس جریان رویدادها است: added (سند ظاهر شد)، modified (سند تغییر کرد) و removed (سند حذف شد). توسعهدهنده میتواند هر رویداد را جداگانه پردازش کند و فقط عناصر رابط کاربری مربوطه را بهروزرسانی کند. این عملکرد بالا را حتی با هزاران سند تضمین میکند، زیرا فقط مؤلفههای تغییر یافته دوباره ترسیم میشوند.
یکی از مزایای کلیدی 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 استفاده میشود، اما برای برنامههایی با خواندن فشرده داده میتوان آن را افزایش داد. همچنین حالت persistent disk cache در دسترس است که از راهاندازی مجدد برنامه باقی میماند. برای مدیریت دسترسی به حالت آفلاین از متدهای 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 و کوروتینهای Kotlin استفاده میشود.
قبل از شروع کار باید پروژه را از طریق Firebase Console به Firebase متصل کرده و فایل google-services.json را به ماژول برنامه اضافه کنید. سپس در build.gradle وابستگی 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 و مخزن برای کار با Firestore ایجاد میشود. مدل شامل فیلدهای id، title، isCompleted و timestamp است. Firestore به طور خودکار data class را به سند تبدیل میکند و از نام فیلدها به عنوان کلید استفاده میکند. برای خواندن دادهها از snapshot listener استفاده میشود که از طریق افزونه snapshotFlow یک Flow برمیگرداند.
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))
}
}
View-model در Flow از مخزن مشترک میشود و لیست کارها را به لایه رابط کاربری ارسال میکند. هنگام افزودن کار جدید، تابع suspend مخزن از طریق scope کوروتین فراخوانی میشود. Firestore به طور خودکار تغییرات را بین همه کلاینتها همگامسازی میکند: اگر یک کاربر کاری را اضافه کند، سایرین آن را در زمان واقعی بدون بارگذاری مجدد صفحه میبینند.
سوالات متداول
Firestore یک پایگاه داده NoSQL با طرح انعطافپذیر بدون جدول و پرسوجوهای JOIN است. دادهها در مجموعههای اسناد ذخیره میشوند نه در ردیفهای جداول. برخلاف SQL، Firestore به تعریف قبلی طرح نیاز ندارد و بدون مهاجرت به طور خودکار مقیاسپذیر است، اما از پرسوجوهای تراکنشی پیچیده بین مجموعهها پشتیبانی نمیکند.
Firestore دارای محدودیت رایگان سخاوتمندانه (طرح Spark) است: 50000 خواندن، 20000 نوشتن و 20000 حذف در روز. پس از تجاوز از طرح Blaze با پرداخت بر اساس مصرف استفاده میشود: 0.06 دلار برای 100000 خواندن و 0.18 دلار برای 100000 نوشتن. قیمت به منطقه و حجم دادههای منتقلشده بستگی دارد.
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 از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید