Firebase Realtime Database হল একটি ক্লাউড JSON রিয়েল-টাইম ডেটাবেস যা Google 2012 সালে মোবাইল এবং ওয়েব অ্যাপ্লিকেশনের জন্য চালু করেছিল। সমস্ত ডেটা একটি বড় JSON ট্রিতে সংরক্ষিত হয় এবং WebSocket সংযোগের মাধ্যমে সংযুক্ত ক্লায়েন্টদের মধ্যে রিয়েল-টাইমে সিঙ্ক্রোনাইজ হয়। অফিসিয়াল ডকুমেন্টেশন অনুযায়ী Firebase, 2025, Realtime Database 200,000 পর্যন্ত একসঙ্গে সংযোগ এবং প্রতি সেকেন্ডে 1000 পর্যন্ত একসঙ্গে লেখা সমর্থন করতে পারে। ডেটাবেসের সার্ভার অবকাঠামোর প্রয়োজন নেই এবং এটি iOS, Android, Web এবং সার্ভার প্ল্যাটফর্মের জন্য SDK প্রদান করে।
মূল বিষয়
Firebase Realtime Database হল একটি ক্লাউড NoSQL ডেটাবেস যা সমস্ত সংযুক্ত ক্লায়েন্টের মধ্যে রিয়েল-টাইমে ডেটা সংরক্ষণ এবং সিঙ্ক্রোনাইজ করে। 2012 সালে Firebase হিসেবে চালু করা হয় (Google অধিগ্রহণের আগে), এটি মোবাইল ডেভেলপারদের জন্য প্রথম ক্লাউড রিয়েল-টাইম ডেটাবেস হয়ে ওঠে। ডেটা JSON ফরম্যাটে উপস্থাপিত হয় এবং একটি স্তরক্রমিক ট্রিতে সংগঠিত হয়, যেখানে প্রতিটি নোডের একটি অনন্য পাথ থাকে।
Realtime Database-এর মূল মূল্য হল অন্তর্নির্মিত সিঙ্ক্রোনাইজেশন। যখন কোনো অ্যাপ্লিকেশন কোনো ডিভাইসে ডেটা পরিবর্তন করে, তখন অন্যান্য সমস্ত সংযুক্ত ক্লায়েন্ট একটি স্থায়ী সংযোগের মাধ্যমে তাত্ক্ষণিকভাবে আপডেট পায়। এটি ক্লায়েন্টদের মধ্যে ডেটা স্থানান্তরের জন্য ডেভেলপারকে নিজস্ব সিঙ্ক্রোনাইজেশন মেকানিজম, WebSocket সার্ভার বা REST API বাস্তবায়নের প্রয়োজনীয়তা দূর করে।
ডেটাবেসটি সমস্ত প্রধান প্ল্যাটফর্মের জন্য SDK প্রদান করে: Android (Java, Kotlin), iOS (Swift, Objective-C), Web (JavaScript), এবং Admin SDK-এর মাধ্যমে সার্ভার পরিবেশ। Google-এর মতে, Realtime Database সারা বিশ্বে 1.5 মিলিয়নেরও বেশি সক্রিয় Firebase প্রকল্পে ব্যবহৃত হয়। আরও আধুনিক Firestore-এর আবির্ভাব সত্ত্বেও, Realtime Database সরল ডেটা কাঠামো সহ প্রকল্পের জন্য একটি জনপ্রিয় পছন্দ হিসেবে রয়ে গেছে।
রিলেশনাল ডেটাবেসের বিপরীতে, Realtime Database টেবিল এবং সারি ব্যবহার করে না। সমস্ত ডেটা একটি একক JSON ট্রি যা নেস্টেড JavaScript অবজেক্টের মতো দেখায়। উদাহরণস্বরূপ, ব্যবহারকারী এবং তাদের বার্তা সংরক্ষণের জন্য একটি স্তরক্রম তৈরি করা হয়: users/userId/name এবং messages/messageId/text। ট্রিতে প্রতিটি পাথ একটি স্ট্রিং, এবং এই পাথ দ্বারা সরাসরি ডেটা অ্যাক্সেস করা যায়।
{
"users": {
"user1": {
"name": "ইভান পেট্রোভ",
"email": "ivan@example.com"
},
"user2": {
"name": "মারিয়া সোকোলোভা",
"email": "maria@example.com"
}
},
"messages": {
"-Nabc123": {
"text": "হ্যালো!",
"userId": "user1"
}
}
}
একটি গুরুত্বপূর্ণ বৈশিষ্ট্য — গভীর নেস্টিং কর্মক্ষমতা প্রভাবিত করে। যখন কোনো অ্যাপ্লিকেশন একটি নির্দিষ্ট পাথে ডেটা পড়ে, তখন এটি সেই পাথের সমস্ত চাইল্ড নোড লোড করে। তাই, ডেটা কাঠামো যতটা সম্ভব ফ্ল্যাট ডিজাইন করার পরামর্শ দেওয়া হয়, 3-4 স্তরের বেশি গভীর নেস্টিং এড়িয়ে চলুন। এই সমস্যা মোকাবেলায়, ডেটা ডিনর্মালাইজেশন ব্যবহার করা হয় — বিভিন্ন ট্রি নোডে তথ্যের নকল করা।
Realtime Database এবং Firestore-কে প্রায়ই Google-এর দুটি ক্লাউড রিয়েল-টাইম ডেটাবেস হিসেবে তুলনা করা হয়। তাদের মধ্যে পছন্দ প্রকল্পের নির্দিষ্ট প্রয়োজনীয়তার উপর নির্ভর করে: কোয়েরি জটিলতা, প্রয়োজনীয় সঙ্গতি এবং প্রত্যাশিত লোড। প্রতিটি ডেটাবেসের শক্তি বোঝা সঠিক আর্কিটেকচারাল সিদ্ধান্ত নিতে সাহায্য করে।
Realtime Database-এর প্রধান সুবিধা হল কম সিঙ্ক লেটেন্সি। যেহেতু সমস্ত ডেটা অতিরিক্ত অ্যাবস্ট্রাকশন লেয়ার ছাড়া একটি JSON ট্রিতে সংরক্ষিত হয়, সিঙ্ক্রোনাইজেশন Firestore-এর তুলনায় দ্রুত হয়। সেই অ্যাপ্লিকেশনের জন্য যেখানে আপডেট ডেলিভারির গতি গুরুত্বপূর্ণ (চ্যাট, অনলাইন গেম, সহযোগী সম্পাদনা সিস্টেম), Realtime Database আরও উপযুক্ত পছন্দ হতে পারে।
Realtime Database সরল ডেটা কাঠামো এবং উচ্চ আপডেট ফ্রিকোয়েন্সি সহ পরিস্থিতির জন্য বেশি উপযুক্ত। সাধারণ উদাহরণ: চ্যাট, রিয়েল-টাইম লাইক, টাইপিং ইন্ডিকেটর, ব্যবহারকারী উপস্থিতি অবস্থা। এটি প্রোটোটাইপ এবং সীমিত বাজেটের প্রকল্পের জন্যও একটি ভাল পছন্দ, কারণ মূল্য নির্ধারণ অপারেশনের সংখ্যার পরিবর্তে ডেটা ভলিউমের উপর ভিত্তি করে।
অন্যদিকে, জটিল কোয়েরি (একাধিক ক্ষেত্র দ্বারা ফিল্টারিং, সাজানো, সমষ্টি) সহ অ্যাপ্লিকেশনের জন্য, Firestore অনেক বেশি শক্তিশালী ক্ষমতা প্রদান করে। Realtime Database শুধুমাত্র একটি প্যারামিটার দ্বারা ফিল্টারিং সমর্থন করে এবং একসঙ্গে একাধিক ক্ষেত্র দ্বারা ফলাফল সাজাতে পারে না। যদি কোনো প্রকল্প ক্লায়েন্ট-সাইডে জটিল ডেটা বিশ্লেষণের পরিকল্পনা করে, তাহলে Firestore আরও ব্যবহারিক পছন্দ হবে।
Realtime Database দ্বিমুখী ডেটা সিঙ্ক্রোনাইজেশনের জন্য একটি স্থায়ী WebSocket সংযোগ ব্যবহার করে। যখন কোনো ক্লায়েন্ট একটি নির্দিষ্ট পাথে setValue বা updateChildren কল করে, তখন ডেটা খোলা চ্যানেলের মাধ্যমে Firebase সার্ভারে পাঠানো হয়। সার্ভার পরিবর্তনগুলি প্রয়োগ করে এবং মিলিসেকেন্ডের মধ্যে সমস্ত সাবস্ক্রাইবড ক্লায়েন্টকে আপডেট বিতরণ করে। প্রতিটি সংযোগ একটি অনন্য সেশন কী দ্বারা চিহ্নিত করা হয়।
সাবস্ক্রিপশন মেকানিজম listeners-এর মাধ্যমে কাজ করে। একজন ডেভেলপার একটি নির্দিষ্ট নোডে পরিবর্তনের সাবস্ক্রাইব করতে পারে (addListenerForSingleValueEvent) বা ক্রমাগত আপডেট পেতে পারে (addValueEventListener)। প্রতিবার ডেটা পরিবর্তিত হলে, নির্দিষ্ট পাথে সম্পূর্ণ ডেটা স্ন্যাপশট সহ onDataChange callback ট্রিগার হয়। এটি Firestore থেকে ভিন্ন, যেখানে শুধুমাত্র পরিবর্তিত ডকুমেন্ট পাওয়া যায় — Realtime Database-এ সর্বদা নোডের সমস্ত ডেটা লোড হয়।
Realtime Database ডিস্ক ক্যাশিং-এর মাধ্যমে Android এবং iOS-এ অফলাইন মোড সমর্থন করে। SDK ডেটার স্থানীয় কপি রাখে এবং নেটওয়ার্ক না থাকলে লেখা অপারেশন প্রক্রিয়াকরণ চালিয়ে যায়। যখন সংযোগ পুনরুদ্ধার হয়, তখন সমস্ত সঞ্চিত পরিবর্তন সার্ভারে পাঠানো হয়। দ্বন্দ্ব সমাধানের জন্য লাস্ট-রাইট-উইনস কৌশল ব্যবহার করা হয়, কিন্তু ডেভেলপার সংঘর্ষ সমাধানের জন্য ServerValue.TIMESTAMP-এর মাধ্যমে কাস্টম লজিক প্রয়োগ করতে পারে।
val database = FirebaseDatabase.getInstance()
val myRef = database.getReference("messages")
// ডেটা লেখা
myRef.push().setValue(
hashMapOf(
"text" to "নতুন বার্তা",
"timestamp" to ServerValue.TIMESTAMP
)
)
// ক্রমাগত আপডেটের সাথে পড়া
myRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val data = snapshot.getValue()
Log.d("TAG", "ডেটা: $data")
}
override fun onCancelled(error: DatabaseError) {
Log.w("TAG", "ত্রুটি: ${error.message}")
}
})
ট্রাফিক এবং কর্মক্ষমতা অপ্টিমাইজ করতে, নির্দিষ্ট চাইল্ড নোডে পরিবর্তন ট্র্যাক করার সময় value listeners-এর পরিবর্তে child listeners ব্যবহার করার পরামর্শ দেওয়া হয়। ChildEventListener চাইল্ড এলিমেন্ট যোগ, সংশোধন, মুছে ফেলা এবং সরানোর জন্য পৃথক callback প্রদান করে, যা UI আপডেটের আরও সুনির্দিষ্ট নিয়ন্ত্রণ এবং প্রতিটি ডেটা পরিবর্তনে সমস্ত তালিকা আইটেম পুনরায় আঁকা এড়াতে দেয়।
Realtime Database ডেটা অ্যাক্সেস নিয়ন্ত্রণের জন্য ঘোষণামূলক নিয়ম ভাষা ব্যবহার করে। নিয়মগুলি বর্ণনা করে যে কে JSON ট্রির প্রতিটি পাথে ডেটা পড়তে এবং লিখতে পারে। প্রতিটি অনুরোধের আগে Firebase সার্ভারে এগুলি পরীক্ষা করা হয় এবং অনুমোদনের জন্য সার্ভার-সাইড লজিকের প্রয়োজন হয় না। নিয়মগুলি নমনীয় অ্যাক্সেস কনফিগারেশনের জন্য ভেরিয়েবল, অন্তর্নির্মিত অবজেক্ট এবং ফাংশন সমর্থন করে।
ডিফল্টরূপে, সমস্ত ব্যবহারকারীর জন্য ডেটাবেস অ্যাক্সেস অস্বীকৃত। ডেভেলপার ট্রির বিভিন্ন স্তরে ".read" এবং ".write" নিয়ম ব্যবহার করে ধীরে ধীরে অ্যাক্সেস খোলে। শর্তগুলি auth ভেরিয়েবলের মাধ্যমে প্রমাণীকরণ, অনুরোধের ধরন (পড়া/লেখা), এবং data অবজেক্টের মাধ্যমে বিদ্যমান ডেটা পরীক্ষা করতে পারে। অতিরিক্তভাবে, নিয়মগুলি newData অবজেক্টের মাধ্যমে লেখা ডেটার বৈধতা সমর্থন করে।
{
"rules": {
"users": {
"$uid": {
// শুধু মালিক নিজের ডেটা পড়তে পারেন
".read": "$uid === auth.uid",
// শুধু মালিক লিখতে পারেন
".write": "$uid === auth.uid",
// লেখার সময় ক্ষেত্রের বৈধতা
".validate": "newData.hasChildren(['name', 'email'])"
}
},
"messages": {
// যে কোনো প্রমাণিত ব্যবহারকারী পড়তে পারেন
".read": "auth !== null",
// শুধু প্রমাণিত ব্যবহারকারী লিখতে পারেন
".write": "auth !== null",
".indexOn": ["timestamp"]
}
}
}
নিয়মগুলি ".indexOn" নির্দেশের মাধ্যমে ডেটা ইনডেক্সিংও সমর্থন করে। এটি ছাড়া, সাজানো (orderByChild) সহ কোয়েরি প্রত্যাখ্যান বা অদক্ষভাবে সম্পাদিত হবে। নির্দিষ্ট ক্ষেত্র দ্বারা সাজানো হয় এমন প্রতিটি পাথের জন্য ইনডেক্স নির্দিষ্ট করা হয়। নিয়মগুলি ক্যাসকেডিং: গভীর নিয়মগুলি মূল নিয়মগুলিকে ওভাররাইড করে, এবং যদি কোনো স্তরে অ্যাক্সেস সংজ্ঞায়িত না হয়, তবে এটি মূল নিয়মের উপর নির্ভর করে অনুমোদিত বা অস্বীকৃত বলে বিবেচিত হয়।
Realtime Database পাঁচটি ডেটা প্রকার সমর্থন করে: String, Number, Boolean, Map (অবজেক্ট), এবং List (অ্যারে)। নেস্টিং গভীরতা 32 স্তরে সীমাবদ্ধ, এবং একটি একক নোডের সর্বোচ্চ আকার 256 MB-এর বেশি হওয়া উচিত নয়। দক্ষ ডেটাবেস কাজের জন্য, ফ্ল্যাট ডেটা কাঠামো ডিজাইন এবং বড় পরিমাণ ডেটা লোড করে এমন গভীর কোয়েরি এড়াতে ডিনর্মালাইজেশন ব্যবহার করার পরামর্শ দেওয়া হয়।
আসুন ব্যবহারকারীর অবস্থা (অনলাইন/অফলাইন) জন্য Android অ্যাপ্লিকেশনে Realtime Database সংহত করার একটি ব্যবহারিক উদাহরণ দেখি। অ্যাপ্লিকেশনটি ব্যবহারকারীদের তাদের বর্তমান অবস্থা সহ একটি তালিকা প্রদর্শন করবে, যা রিয়েল-টাইমে আপডেট হয়। প্রদর্শনের জন্য ব্যবহারকারী সনাক্তকরণের জন্য Firebase Authentication এবং অ্যাসিঙ্ক্রোনাস অপারেশনের জন্য করুটিন ব্যবহার করা হয়।
শুরু করতে, অ্যাপ মডিউল build.gradle ফাইলে firebase-database-ktx নির্ভরতা যোগ করুন। সমস্ত উপাদানের সামঞ্জস্য নিশ্চিত করার জন্য লাইব্রেরি সংস্করণ Firebase BoM-এর মাধ্যমে পরিচালিত হয়। নির্ভরতা যোগ করার পর, Firebase-কে Application ক্লাসে বা ViewModel-এ লেজি আরম্ভীকরণের মাধ্যমে আরম্ভ করতে হবে।
dependencies {
implementation platform("com.google.firebase:firebase-bom:33.0.0")
implementation "com.google.firebase:firebase-database-ktx"
implementation "com.google.firebase:firebase-auth-ktx"
}
কনফিগারেশনের পর, ব্যবহারকারীদের সাথে কাজ করার জন্য একটি রিপোজিটরি তৈরি করা হয়। প্রতিটি ব্যবহারকারী name, email এবং status ক্ষেত্র সহ /users/{uid} ট্রিতে একটি নোড দ্বারা উপস্থাপিত হয়। অবস্থা ট্র্যাকিংয়ের জন্য onDisconnect ব্যবহার করা হয় — একটি বিশেষ Firebase প্রক্রিয়া যা ক্লায়েন্ট সংযোগ বিচ্ছিন্ন হলে স্বয়ংক্রিয়ভাবে একটি লেখা অপারেশন সম্পাদন করে। এটি নিশ্চিত করে যে ক্লায়েন্টে অতিরিক্ত কোড ছাড়াই অ্যাপ বন্ধ বা নেটওয়ার্ক হারালে ব্যবহারকারীর অবস্থা "offline"-এ পরিবর্তিত হয়।
class PresenceRepository {
private val database = FirebaseDatabase.getInstance()
private val auth = FirebaseAuth.getInstance()
private val presenceRef = database
.getReference("presence")
fun trackPresence() {
val uid = auth.currentUser?.uid ?: return
val userRef = presenceRef.child(uid)
userRef.onDisconnect().setValue("offline")
userRef.setValue("online")
}
fun getPresenceStream(): Flow<Map<String, String>> =
presenceRef.snapshotFlow()
.map { snapshot ->
(snapshot.value as? Map<*, *>)
?.mapKeys { it.key.toString() }
?.mapValues { it.value.toString() }
?: emptyMap()
}
}
উদাহরণের মূল উপাদান হল onDisconnect। এই প্রক্রিয়াটি একটি লেখা অপারেশন সেট করার অনুমতি দেয় যা ক্লায়েন্ট সংযোগ বিচ্ছিন্ন হলে সার্ভারে সম্পাদিত হবে। এই ক্ষেত্রে, ব্যবহারকারী সংযোগ বিচ্ছিন্ন হলে, অ্যাপ্লিকেশন বন্ধ হওয়ার ঘটনা পরিচালনা করার প্রয়োজন ছাড়াই তাদের অবস্থা স্বয়ংক্রিয়ভাবে "offline"-এ সেট হয়। যদি অ্যাপ ক্র্যাশ হয়, Firebase নিজেই onDisconnect অপারেশন সম্পাদন করবে এবং অন্যান্য ব্যবহারকারীরা সঠিক অবস্থা দেখতে পাবেন।
সচরাচর জিজ্ঞাসা
Realtime Database একটি JSON ট্রিতে ডেটা সংরক্ষণ করে এবং কম সিঙ্ক লেটেন্সি প্রদান করে। Firestore ডকুমেন্ট সংগ্রহ ব্যবহার করে, জটিল কোয়েরি এবং শক্তিশালী সঙ্গতি সমর্থন করে। Realtime Database সরল চ্যাট এবং অবস্থার জন্য ভাল, Firestore জটিল ডেটা কাঠামো এবং বিশ্লেষণ সহ অ্যাপ্লিকেশনের জন্য ভাল।
একক Realtime Database নোডের সর্বোচ্চ আকার হল 256 MB। নেস্টিং গভীরতা 32 স্তরে সীমাবদ্ধ। একটি Firebase প্রকল্পের জন্য, একাধিক Realtime Database ইনস্ট্যান্স তৈরি করা যেতে পারে (Spark পরিকল্পনায় 5 পর্যন্ত এবং Blaze পরিকল্পনায় 100 পর্যন্ত), যা বিভিন্ন ইনস্ট্যান্সে ডেটা বিতরণের অনুমতি দেয়।
Realtime Database Firebase Authentication-এর সাথে সংহত হয়। নিরাপত্তা নিয়মে প্রমাণিত ব্যবহারকারীর uid সম্বলিত auth ভেরিয়েবল উপলব্ধ। ডেভেলপার ডেটা মালিকের uid পরীক্ষা করে JSON ট্রির পৃথক নোড স্তরে অ্যাক্সেস সীমাবদ্ধ করতে পারে। বেনামী এবং অপ্রমাণিত ব্যবহারকারীদের জন্য auth = null হয়।
হ্যাঁ, Realtime Database runTransaction পদ্ধতির মাধ্যমে লেনদেন সমর্থন করে। একটি লেনদেন একটি একক নোডের জন্য পড়া-পরিবর্তন-লেখা অপারেশনের পারমাণবিকতা নিশ্চিত করে। যখন একসঙ্গে পরিবর্তন ঘটে, তখন লেনদেন বর্তমান ডেটা সহ পুনরায় চেষ্টা করা হয়। এটি কাউন্টার, রেটিং এবং অন্যান্য পরিস্থিতির জন্য দরকারী যেখানে ডেটা সঙ্গতি গুরুত্বপূর্ণ।
হ্যাঁ, Realtime Database Android এবং iOS-এ অফলাইন মোড সমর্থন করে। SDK ডেটা স্থানীয়ভাবে ক্যাশ করে এবং নেটওয়ার্ক ছাড়া লেখা অপারেশন প্রক্রিয়াকরণ চালিয়ে যায়। যখন সংযোগ পুনরুদ্ধার হয়, তখন সমস্ত সঞ্চিত পরিবর্তন সার্ভারের সাথে সিঙ্ক্রোনাইজ হয়। অফলাইন মোড সক্ষম করতে, পছন্দসই নোডে keepSynced(true) পদ্ধতি ব্যবহার করুন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন