শুরু করুন
যদি আপনি এখনও আপনার অ্যাপ সেট আপ না করে থাকেন এবং ডাটাবেসে অ্যাক্সেস না করে থাকেন, তাহলে প্রথমে Get Started নির্দেশিকাটি দেখুন।
একটি ডাটাবেস রেফারেন্স পান
ডাটাবেসে ডেটা লেখার জন্য, আপনার DatabaseReference এর একটি উদাহরণ প্রয়োজন:
// Get the root reference location of the database. firebase::database::DatabaseReference dbref = database->GetReference();
ডেটা সংরক্ষণ করা হচ্ছে
Firebase Realtime Database ডেটা লেখার জন্য চারটি পদ্ধতি রয়েছে:
| পদ্ধতি | সাধারণ ব্যবহার |
|---|---|
SetValue() | একটি নির্দিষ্ট পাথে ডেটা লিখুন বা প্রতিস্থাপন করুন, যেমন users/<user-id>/<username> । |
PushChild() | ডেটার তালিকায় যোগ করুন। প্রতিবার যখন আপনি Push() কল করেন, তখন Firebase একটি অনন্য কী তৈরি করে যা একটি অনন্য শনাক্তকারী হিসেবেও ব্যবহার করা যেতে পারে, যেমন user-scores/<user-id>/<unique-score-id> । |
UpdateChildren() | সমস্ত ডেটা প্রতিস্থাপন না করে একটি নির্দিষ্ট পথের জন্য কিছু কী আপডেট করুন। |
RunTransaction() | সমসাময়িক আপডেটের ফলে দূষিত হতে পারে এমন জটিল ডেটা আপডেট করুন। |
রেফারেন্সে ডেটা লিখুন, আপডেট করুন বা মুছুন
মৌলিক লেখার ক্রিয়াকলাপ
মৌলিক লেখার ক্রিয়াকলাপের জন্য, আপনি SetValue() ব্যবহার করে একটি নির্দিষ্ট রেফারেন্সে ডেটা সংরক্ষণ করতে পারেন, সেই পাথে বিদ্যমান যেকোনো ডেটা প্রতিস্থাপন করতে পারেন। আপনি এই পদ্ধতিটি ব্যবহার করে JSON দ্বারা গৃহীত প্রকারগুলিকে একটি Variant প্রকারের মাধ্যমে পাস করতে পারেন যা সমর্থন করে:
- শূন্য (এটি ডেটা মুছে ফেলে)
- পূর্ণসংখ্যা (৬৪-বিট)
- দ্বিগুণ নির্ভুলতা ভাসমান বিন্দু সংখ্যা
- বুলিয়ান
- স্ট্রিং
- ভেরিয়েন্টের ভেক্টর
- স্ট্রিং থেকে ভেরিয়েন্টের মানচিত্র
এইভাবে SetValue() ব্যবহার করলে নির্দিষ্ট স্থানে থাকা ডেটা ওভাররাইট হয়ে যায়, যার মধ্যে যেকোনো চাইল্ড নোডও অন্তর্ভুক্ত থাকে। তবে, আপনি সম্পূর্ণ অবজেক্টটি পুনর্লিখন না করেও চাইল্ড আপডেট করতে পারেন। আপনি যদি ব্যবহারকারীদের তাদের প্রোফাইল আপডেট করার অনুমতি দিতে চান তবে আপনি নিম্নলিখিতভাবে ব্যবহারকারীর নাম আপডেট করতে পারেন:
dbref.Child("users").Child(userId).Child("username").SetValue(name);
তথ্যের তালিকায় যুক্ত করুন
মাল্টিইউজার অ্যাপ্লিকেশনের তালিকায় ডেটা যোগ করার জন্য PushChild() পদ্ধতি ব্যবহার করুন। নির্দিষ্ট Firebase রেফারেন্সে নতুন চাইল্ড যোগ করার সময় PushChild() পদ্ধতিটি একটি অনন্য কী তৈরি করে। তালিকার প্রতিটি নতুন উপাদানের জন্য এই স্বয়ংক্রিয়ভাবে তৈরি কীগুলি ব্যবহার করে, একাধিক ক্লায়েন্ট লেখার দ্বন্দ্ব ছাড়াই একই সময়ে একই স্থানে বাচ্চাদের যোগ করতে পারে। PushChild() দ্বারা তৈরি অনন্য কীটি একটি টাইমস্ট্যাম্পের উপর ভিত্তি করে তৈরি করা হয়, তাই তালিকার আইটেমগুলি স্বয়ংক্রিয়ভাবে কালানুক্রমিকভাবে সাজানো হয়।
আপনি PushChild() পদ্ধতি দ্বারা ফেরত আসা নতুন ডেটার রেফারেন্স ব্যবহার করে সন্তানের স্বয়ংক্রিয়ভাবে তৈরি কী বা সন্তানের জন্য সেট ডেটার মান পেতে পারেন। PushChild() রেফারেন্সে GetKey() কল করলে স্বয়ংক্রিয়ভাবে তৈরি কীর মান ফেরত পাওয়া যায়।
নির্দিষ্ট ক্ষেত্রগুলি আপডেট করুন
অন্য চাইল্ড নোডগুলিকে ওভাররাইট না করে একটি নোডের নির্দিষ্ট চাইল্ড্রেনগুলিতে একই সাথে লেখার জন্য, UpdateChildren() পদ্ধতিটি ব্যবহার করুন।
UpdateChildren() কল করার সময়, আপনি কীটির জন্য একটি পাথ নির্দিষ্ট করে নিম্ন-স্তরের চাইল্ড মানগুলি আপডেট করতে পারেন। যদি ডেটা আরও ভালভাবে স্কেল করার জন্য একাধিক স্থানে সংরক্ষণ করা হয়, তাহলে আপনি data fan-out ব্যবহার করে সেই ডেটার সমস্ত উদাহরণ আপডেট করতে পারেন। উদাহরণস্বরূপ, একটি গেমের LeaderboardEntry ক্লাস এইরকম হতে পারে:
class LeaderboardEntry { std::string uid; int score = 0; public: LeaderboardEntry() { } LeaderboardEntry(std::string uid, int score) { this->uid = uid; this->score = score; } std::map<std::string, Object> ToMap() { std::map<string, Variant> result = new std::map<string, Variant>(); result["uid"] = Variant(uid); result["score"] = Variant(score); return result; } }
একটি LeaderboardEntry তৈরি করতে এবং একই সাথে সাম্প্রতিক স্কোর ফিড এবং ব্যবহারকারীর নিজস্ব স্কোর তালিকায় এটি আপডেট করতে, গেমটি নিম্নলিখিত কোড ব্যবহার করে:
void WriteNewScore(std::string userId, int score) { // Create new entry at /user-scores/$userid/$scoreid and at // /leaderboard/$scoreid simultaneously std::string key = dbref.Child("scores").PushChild().GetKey(); LeaderBoardEntry entry = new LeaderBoardEntry(userId, score); std::map<std::string, Variant> entryValues = entry.ToMap(); std::map<string, Variant> childUpdates = new std::map<string, Variant>(); childUpdates["/scores/" + key] = entryValues; childUpdates["/user-scores/" + userId + "/" + key] = entryValues; dbref.UpdateChildren(childUpdates); }
এই উদাহরণে PushChild() ব্যবহার করে /scores/$key তে সকল ব্যবহারকারীর জন্য এন্ট্রি সম্বলিত নোডে একটি এন্ট্রি তৈরি করা হয় এবং একই সাথে key() দিয়ে কীটি পুনরুদ্ধার করা হয়। এরপর /user-scores/$userid/$key তে ব্যবহারকারীর স্কোরে দ্বিতীয় এন্ট্রি তৈরি করতে কীটি ব্যবহার করা যেতে পারে।
এই পাথগুলি ব্যবহার করে, আপনি JSON ট্রিতে একাধিক অবস্থানে UpdateChildren() এ একটি কলের মাধ্যমে একযোগে আপডেট করতে পারেন, যেমন এই উদাহরণটি কীভাবে উভয় অবস্থানে নতুন এন্ট্রি তৈরি করে। এইভাবে করা একযোগে আপডেটগুলি পারমাণবিক: হয় সমস্ত আপডেট সফল হয় অথবা সমস্ত আপডেট ব্যর্থ হয়।
ডেটা মুছুন
ডেটা মুছে ফেলার সবচেয়ে সহজ উপায় হল সেই ডেটার অবস্থানের রেফারেন্সে RemoveValue() কল করা।
আপনি SetValue() অথবা UpdateChildren() মতো অন্য একটি লেখার অপারেশনের জন্য একটি null Variant মান নির্দিষ্ট করেও মুছে ফেলতে পারেন। আপনি UpdateChildren() এর সাথে এই কৌশলটি ব্যবহার করে একটি একক API কলে একাধিক শিশু মুছে ফেলতে পারেন।
আপনার ডেটা কখন প্রতিশ্রুতিবদ্ধ তা জানুন।
আপনার ডেটা কখন Firebase Realtime Database সার্ভারে প্রতিশ্রুতিবদ্ধ তা জানতে, সাফল্যের জন্য ভবিষ্যতের ফলাফলটি পরীক্ষা করুন।
লেনদেন হিসেবে ডেটা সংরক্ষণ করুন
যখন আপনি এমন ডেটা নিয়ে কাজ করেন যা সমসাময়িক পরিবর্তনের মাধ্যমে দূষিত হতে পারে, যেমন ইনক্রিমেন্টাল কাউন্টার, তখন আপনি একটি লেনদেন অপারেশন ব্যবহার করতে পারেন। আপনি এই অপারেশনটিকে একটি DoTransaction ফাংশন দেন। এই আপডেট ফাংশনটি ডেটার বর্তমান অবস্থাকে একটি আর্গুমেন্ট হিসাবে নেয় এবং আপনি যে নতুন পছন্দসই অবস্থা লিখতে চান তা ফেরত দেয়। যদি আপনার নতুন মান সফলভাবে লেখার আগে অন্য কোনও ক্লায়েন্ট অবস্থানে লেখে, তাহলে আপনার আপডেট ফাংশনটি নতুন বর্তমান মান সহ আবার কল করা হবে এবং লেখার পুনরায় চেষ্টা করা হবে।
উদাহরণস্বরূপ, একটি গেমে আপনি ব্যবহারকারীদের সর্বোচ্চ পাঁচটি স্কোরের একটি লিডারবোর্ড আপডেট করার অনুমতি দিতে পারেন:
void AddScoreToLeaders(std::string email, long score, DatabaseReference leaderBoardRef) { leaderBoardRef.RunTransaction([](firebase::database::MutableData* mutableData) { if (mutableData.children_count() >= MaxScores) { long minScore = LONG_MAX; MutableData *minVal = null; std::vector<MutableData> children = mutableData.children(); std::vector<MutableData>::iterator it; for (it = children.begin(); it != children.end(); ++it) { if (!it->value().is_map()) continue; long childScore = (long)it->Child("score").value().int64_value(); if (childScore < minScore) { minScore = childScore; minVal = &*it; } } if (minScore > score) { // The new score is lower than the existing 5 scores, abort. return kTransactionResultAbort; } // Remove the lowest score. children.Remove(minVal); } // Add the new high score. std::map<std::string, Variant> newScoreMap = new std::map<std::string, Variant>(); newScoreMap["score"] = score; newScoreMap["email"] = email; children.Add(newScoreMap); mutableData->set_value(children); return kTransactionResultSuccess; }); }
যদি একাধিক ব্যবহারকারী একই সময়ে স্কোর রেকর্ড করে অথবা ক্লায়েন্টের পুরনো ডেটা থাকে, তাহলে লেনদেন ব্যবহার করলে লিডারবোর্ড ভুল হতে বাধা দেয়। যদি লেনদেন বাতিল করা হয়, তাহলে সার্ভার ক্লায়েন্টকে বর্তমান মান ফেরত দেয়, যা আপডেট করা মান সহ আবার লেনদেন চালায়। লেনদেন গৃহীত না হওয়া পর্যন্ত বা অনেক প্রচেষ্টা না করা পর্যন্ত এটি পুনরাবৃত্তি হয়।
অফলাইনে ডেটা লিখুন
যদি কোনও ক্লায়েন্ট তার নেটওয়ার্ক সংযোগ হারিয়ে ফেলে, তাহলে আপনার অ্যাপটি সঠিকভাবে কাজ করতে থাকবে।
ফায়ারবেস ডাটাবেসের সাথে সংযুক্ত প্রতিটি ক্লায়েন্ট যেকোনো সক্রিয় ডেটার নিজস্ব অভ্যন্তরীণ সংস্করণ বজায় রাখে। যখন ডেটা লেখা হয়, তখন প্রথমে এটি এই স্থানীয় সংস্করণে লেখা হয়। তারপর ফায়ারবেস ক্লায়েন্ট সেই ডেটাকে "সর্বোত্তম প্রচেষ্টা" ভিত্তিতে দূরবর্তী ডাটাবেস সার্ভার এবং অন্যান্য ক্লায়েন্টদের সাথে সিঙ্ক্রোনাইজ করে।
ফলস্বরূপ, সার্ভারে কোনও ডেটা লেখার আগেই ডাটাবেসে সমস্ত লেখা স্থানীয় ইভেন্টগুলিকে অবিলম্বে ট্রিগার করে। এর অর্থ হল নেটওয়ার্ক লেটেন্সি বা সংযোগ নির্বিশেষে আপনার অ্যাপটি প্রতিক্রিয়াশীল থাকে।
একবার সংযোগ পুনঃস্থাপিত হয়ে গেলে, আপনার অ্যাপটি উপযুক্ত ইভেন্টের সেট গ্রহণ করে যাতে ক্লায়েন্টটি কোনও কাস্টম কোড না লিখেই বর্তমান সার্ভারের অবস্থার সাথে সিঙ্ক করে।