Firebase Realtime Database یک پایگاه داده NoSQL ابری گوگل با همگامسازی تغییرات در زمان واقعی از طریق اتصال دائمی WebSocket است. دادهها به صورت یک درخت JSON واحد ذخیره میشوند و هر تغییری در هر گره بلافاصله به همه کلاینتهای متصل تحویل داده میشود. طبق دادههای Google, 2026، Realtime Database تا 200 هزار اتصال همزمان به یک نمونه را پشتیبانی میکند. این سرویس با محدودیت رایگان 1 گیگابایت ذخیرهسازی و 10 گیگابایت ترافیک در ماه ارائه میشود.
نکات کلیدی
Firebase Realtime Database یکی از اولین پایگاههای داده ابری بلادرنگ است که توسط گوگل به همراه Firebase در سال 2012 راهاندازی شد. این یک پایگاه داده NoSQL است که دادهها را به صورت یک درخت JSON واحد ذخیره میکند که از طریق یک URL قابل دسترسی است. SDKهای کلاینت (Android, iOS, Web) از طریق WebSocket در گرههای خاص درخت مشترک میشوند و با هر تغییر داده بهروزرسانی دریافت میکنند — بدون پینگ کردن سرور و بدون پیادهسازی مکانیزم Push.
Firebase اصلی در سال 2011 توسط جیمز تمپلین و اندرو لی تأسیس شد و اولین محصول آن دقیقاً Realtime Database بود. پس از خرید توسط گوگل در سال 2014 (به گفته TechCrunch — به مبلغ 50 تا 100 میلیون دلار)، این پایگاه داده در Google Cloud ادغام شد و پهنای باند بسیار بالاتری دریافت کرد. در سال 2017، گوگل Firestore را به عنوان جایگزین تکاملی اعلام کرد، اما Realtime Database همچنان به طور فعال پشتیبانی و بهروزرسانی میشود. طبق دادههای Google (2026)، Realtime Database هنوز در بیش از 1.5 میلیون پروژه فعال استفاده میشود.
تعرفه Spark (رایگان) شامل: 1 گیگابایت ذخیرهسازی، 10 گیگابایت داده دانلودی در ماه، 100 اتصال همزمان و پشتیبانی از پایگاه داده در یک منطقه است. در تعرفه Blaze (pay-as-you-go) هزینه برای ذخیرهسازی اضافی (1 دلار/گیگابایت)، ترافیک (0.12 دلار/گیگابایت) و اتصالات همزمان (5 دلار به ازای هر 100 هزار بیش از حد مجاز) دریافت میشود. برای آزمایش، حالت شبیهسازی نیز در دسترس است — firebase emulators:start — که Realtime Database را بدون اتصال به ابر به صورت محلی اجرا میکند.
Realtime Database جدول، مجموعه یا سند ندارد — همه چیز یک درخت JSON واحد است که در آدرس https://project-name-default-rtdb.firebaseio.com/ در دسترس است. هر کلید درخت یا یک مقدار نهایی (رشته، عدد، boolean، null) است یا یک گره تو در تو با کلیدهای فرزند. موتور پایگاه داده از JOIN، زیرمجموعه یا تجمیع پشتیبانی نمیکند — یک پرس و جو همیشه محتویات یک گره را با تمام عناصر فرزند آن برمیگرداند.
به دلیل عدم وجود JOIN در Realtime Database، نرمالسازی داده اجباری است. به جای درخت تو در تو (کاربر → لیست پستهای او) دادهها به لیستهای مسطح با ارجاع از طریق کلیدها تقسیم میشوند. این رویکرد استاندارد است: دادهها غیرنرمال میشوند تا خواندن یک گره کل زمینه را نکشد. برای مثال، لیست پیامهای چت جدا از پروفایلهای کاربران ذخیره میشود و هر پست فقط ID نویسنده را دارد، نه کل پروفایل او را.
| رویکرد | نمونه ساختار | مشکل |
|---|---|---|
| تو در تو | users/{uid}/posts/{postId}/content | خواندن user تمام پستها را بارگذاری میکند |
| مسطح | posts/{postId}/authorId + users/{uid}/name | به دو پرس و جو نیاز دارد |
| غیرنرمال | posts/{postId}/authorName (کپی شده) | تکرار در بهروزرسانی |
پرس و جوها در Realtime Database با استفاده از filter (orderByChild, orderByKey, orderByValue, limitToFirst, limitToLast, equalTo, startAt, endAt) انجام میشوند. بر خلاف Firestore، ایندکسها به صورت دستی از طریق بخش Rules (.indexOn) ایجاد میشوند. اگر ایندکس اعلام نشده باشد، پرس و جو با مرتبسازی خطای PERMISSION_DENIED برمیگرداند. پرس و جوها فقط روی یک فیلد کار میکنند — پرس و جوهای ترکیبی (فیلتر بر اساس قیمت + مرتبسازی بر اساس تاریخ) پشتیبانی نمیشوند. برای فیلتر کردن پیچیده، دادهها اغلب در گرههای مختلف با کلیدهای مرتبسازی متفاوت تکرار میشوند.
انتخاب بین Realtime Database و Firestore یکی از تصمیمهای معماری رایج هنگام شروع پروژه است. گوگل Firestore را برای اکثر برنامههای جدید توصیه میکند، اما Realtime Database برای سناریوهایی که تأخیر حداقلی انتقال داده حیاتی است، بهترین انتخاب باقی میماند.
سناریوی اول — بازیهای چندنفره با همگامسازی وضعیت (شطرنج، بازیهای ورق، اکشن بلادرنگ). تأخیر Realtime Database 10-30 میلیثانیه در مقابل 50-100 میلیثانیه برای Firestore در یک منطقه است. سناریوی دوم — چتها و پیامرسانها با تعداد بالای پیام. Realtime Database بر اساس حجم داده تعرفهگذاری میشود نه تعداد نوشتهها، که آن را در فرکانس بیش از 1 پیام در ثانیه به طور قابل توجهی ارزانتر از Firestore میکند. سناریوی سوم — حضور (presence) کاربران آنلاین/آفلاین، جایی که کنترلکنندههای onDisconnect Realtime Database امکان تنظیم اتمی وضعیت را در هنگام قطع اتصال فراهم میکنند.
طبق دادههای Google (2026)، حدود 15% از پروژههای جدید Firebase آگاهانه Realtime Database را انتخاب میکنند — زمانی که تیم نیازمندیهای تأخیر، ساختار داده و بودجه را به وضوح درک میکند. در 85% موارد باقیمانده، Firestore به دلیل مقیاسپذیری بهتر، پرس و جوهای قدرتمندتر و تکرار خودکار انتخاب امنتری است.
اتصال Realtime Database به برنامه Android با افزودن وابستگی firebase-database-ktx در build.gradle انجام میشود. شیء FirebaseDatabase از طریق getInstance(url) در دسترس است — میتوان به چندین پایگاه داده در یک پروژه Firebase متصل شد. پس از مقداردهی اولیه، SDK به طور خودکار اتصال WebSocket با سرور برقرار کرده و همگامسازی داده را آغاز میکند.
dependencies {
implementation(platform("com.google.firebase:firebase-bom:33.1.0"))
implementation("com.google.firebase:firebase-database-ktx")
}
// مقداردهی اولیه با URL سفارشی
val database = FirebaseDatabase.getInstance(
"https://my-project-default-rtdb.firebaseio.com/"
)
val ref = database.getReference("chats")
Realtime Database از شیء DatabaseReference برای همه عملیات استفاده میکند. setValue() دادهها را در گره مشخص مینویسد و تمام محتوای آن را کاملاً جایگزین میکند. push() به طور خودکار یک کلید یکتا (بر اساس برچسب زمانی) برای افزودن عنصر به لیست تولید میکند — این روش استاندارد برای ایجاد پیامهای چت، پستها و رکوردها است. updateChildren() چندین گره را به صورت اتمی در یک عملیات تغییر میدهد. addValueEventListener در تغییرات گره مشترک میشود و با هر بهروزرسانی داده callback دریافت میکند.
data class Message(
val author: String = "",
val text: String = "",
val timestamp: Long = ServerValue.TIMESTAMP
)
class ChatRepository(private val ref: DatabaseReference) {
fun sendMessage(author: String, text: String) {
val msg = Message(author = author, text = text)
ref.child("messages").push().setValue(msg)
}
fun observeMessages(): Flow<List<Message>> = callbackFlow {
val listener = ref.child("messages")
.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val messages = snapshot.children.mapNotNull { it.getValue(Message::class.java) }
trySend(messages)
}
override fun onCancelled(error: DatabaseError) {}
})
awaitClose { ref.removeEventListener(listener) }
}
}
مکانیزم همگامسازی Realtime Database بر اساس پروتکل WebSocket (قبلاً — long-polling) است. کلاینت درخواست اشتراک در یک گره خاص را ارسال میکند و سرور اتصال را باز نگه میدارد. با هر تغییر داده در گره مشترک، سرور JSON کامل آن گره را برای کلاینت ارسال میکند. SDK در سمت کلاینت به طور خودکار وضعیت محلی را بهروزرسانی کرده و callbackهای مربوطه (onDataChange) را فراخوانی میکند.
OnDisconnect — قابلیت منحصر به فرد Realtime Database که در Firestore وجود ندارد. توسعهدهنده میتواند عملیات نوشتاری را ثبت کند که در صورت قطع اتصال کلاینت به طور خودکار روی سرور اجرا میشود. این برای وضعیتهای حضور استفاده میشود: "user123/status": "online" با onDisconnect.setValue("offline"). اگر کاربر برنامه را بسته یا اینترنت خود را از دست داده باشد، سرور به طور خودکار وضعیت را "offline" تنظیم میکند، حداکثر در عرض 3 دقیقه (قابل تنظیم در کنسول Firebase).
Persistence در Realtime Database با یک خط فعال میشود: FirebaseDatabase.getInstance().setPersistenceEnabled(true). SDK آخرین وضعیت همه گرههای مشترک را روی دیسک کش میکند (به طور پیشفرض تا 10 مگابایت، قابل تنظیم تا 100 مگابایت). هنگام قطع اتصال، کلاینت با دادههای کش شده به کار ادامه میدهد و تمام عملیات نوشتن در صف قرار میگیرند. وقتی اتصال بازیابی شد، SDK تمام تغییرات انباشته شده را به ترتیب صحیح (FIFO) به سرور ارسال میکند.
طبق دادههای Google (2026)، برنامههای دارای کش persistence فعال، در هنگام قطع اتصال 40% کمتر دادههای کاربر را از دست میدهند. با این حال، اگر کلاینت بیش از 1000 عملیات معوق جمعآوری کرده باشد، سرور ممکن است همه آنها را رد کرده و درخواست همگامسازی کامل کند — این یک مکانیزم محافظتی در برابر کلاینتهای قدیمی است.
Security Rules در Realtime Database یک پیکربندی JSON است که مشخص میکند چه کسی و تحت چه شرایطی میتواند دادهها را در هر گره بخواند و بنویسد. قوانین روی سرور Google کار میکنند و قبل از هر عملیات اجرا میشوند. به طور پیشفرض (در تولید) توصیه میشود قوانین را در حالت "بسته" تنظیم کنید — فقط کاربران احراز هویت شده دسترسی دارند.
قوانین Realtime Database در قالب JSON با بخشهای .read، .write، .validate، .indexOn نوشته میشوند. بر خلاف Firestore (که از نحو match استفاده میکند)، Realtime Database از اشیاء تو در تو استفاده میکند که ساختار داده را تکرار میکنند. شرایط auth (احراز هویت)، data (دادههای موجود)، newData (دادههای جدید در هنگام نوشتن) و now (زمان سرور) را بررسی میکنند. قوانین اعتبارسنجی (.validate) امکان بررسی انواع، محدوده مقادیر و ساختار داده را فراهم میکنند.
{
"rules": {
"users": {
"$uid": {
".read": "auth.uid === $uid",
".write": "auth.uid === $uid",
".validate": "newData.hasChildren(['name', 'email'])"
}
},
"messages": {
".indexOn": ["timestamp"],
"$msgId": {
".read": true,
".write": "auth.uid !== null",
".validate": "newData.child('text').isString() && newData.child('text').val().length <= 500"
}
}
}
}
قوانین Realtime Database به صورت آبشاری به ارث میرسند — اگر در سطح بالایی .read = false باشد، همه گرههای فرزند بدون توجه به قوانین خودشان برای خواندن غیرقابل دسترس هستند. Firebase یک شبیهساز قوانین در کنسول ارائه میدهد که میتوان عملیات را با tokenهای مختلف auth قبل از استقرار آزمایش کرد. توصیه میشود همیشه قوانین را در شبیهساز آزمایش کنید — یک خطا در قانون میتواند دسترسی به دادههای خصوصی همه کاربران را باز کند. طبق دادههای Google (2026)، 40% نشت دادهها در پروژههای Firebase ناشی از قوانین امنیتی نادرست پیکربندی شده است.
سوالات متداول
تا 200 هزار اتصال همزمان به یک نمونه پایگاه داده. در صورت تجاوز از حد مجاز، اتصالات جدید مسدود میشوند. برای مقیاسبندی از sharding روی چند پایگاه داده استفاده میشود.
از onDisconnect استفاده کنید — عملیات نوشتن "offline" را در هنگام قطع اتصال ثبت کنید. سرور به طور خودکار آن را هنگام قطع WebSocket اجرا میکند. به طور جداگانه اتصال را از طریق .info/connected پیگیری کنید.
.indexOn را در Security Rules بررسی کنید — بدون ایندکس اعلام شده، پرس و جو با orderByChild خطای PERMISSION_DENIED برمیگرداند. همچنین مطمئن شوید دادهها در گره صحیح نوشته شدهاند و خواننده مجوز .read دارد.
Firebase Console خروجی از Realtime Database به Firestore را با یک کلیک فراهم میکند. ساختار JSON به مجموعهها و اسناد تبدیل میشود. برای مهاجرت سفارشی از Admin SDK استفاده کنید.
خیر، ذخیره رمزهای عبور در Realtime Database توسط قوانین امنیتی Google ممنوع است. برای احراز هویت از Firebase Auth استفاده کنید — هش رمزهای عبور در ذخیرهگاه ایزولهای نگهداری میشوند که از طریق SDK Realtime Database قابل دسترسی نیست.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید