সি ++ এর জন্য ফায়ারবেস রিয়েলটাইম ডেটাবেস সহ ডেটা সংরক্ষণ করা

এবার শুরু করা যাক

দেখুন Get Started যদি আপনি না এখনও আপনার অ্যাপ এবং অ্যাক্সেস ডাটাবেস গঠন করেছি প্রথম গাইড।

একটি ডাটাবেস রেফারেন্স পান

ডাটাবেজ ডেটা লিখতে, আপনি একটি দৃষ্টান্ত প্রয়োজন DatabaseReference :

    // Get the root reference location of the database.
    firebase::database::DatabaseReference dbref = database->GetReference();

ডেটা সেভ করা

ফায়ারবেস রিয়েলটাইম ডাটাবেসে ডেটা লেখার জন্য চারটি পদ্ধতি রয়েছে:

পদ্ধতি সাধারণ ব্যবহার
SetValue() লিখুন বা এই ধরনের একটি সংজ্ঞায়িত পথে ডেটা, প্রতিস্থাপন users/<user-id>/<username>
PushChild() ডেটার তালিকায় যোগ করুন। প্রতিটি সময় আপনি কল Push() , Firebase যেমন একটি অনন্য কী যে একটি অনন্য শনাক্তকারী হিসেবে ব্যবহার করা যেতে পারে, উত্পন্ন user-scores/<user-id>/<unique-score-id>
UpdateChildren() সমস্ত ডেটা প্রতিস্থাপন না করে একটি সংজ্ঞায়িত পথের জন্য কিছু কী আপডেট করুন।
RunTransaction() জটিল ডেটা আপডেট করুন যা একযোগে আপডেট দ্বারা দূষিত হতে পারে।

একটি রেফারেন্সে ডেটা লিখুন, আপডেট করুন বা মুছে দিন

মৌলিক লেখার ক্রিয়াকলাপ

মৌলিক লেখার অপারেশন জন্য, আপনি ব্যবহার করতে পারেন SetValue() একটি নির্দিষ্ট রেফারেন্স এ ডেটা সংরক্ষণ, যে পথ যে কোনো বিদ্যমান তথ্য প্রতিস্থাপন। আপনি JSON দ্বারা গৃহীত প্রকারগুলি একটি বৈকল্পিক প্রকারের মাধ্যমে পাস করতে এই পদ্ধতিটি ব্যবহার করতে পারেন যা সমর্থন করে:

  • নাল (এটি ডেটা মুছে ফেলে)
  • পূর্ণসংখ্যা (64-বিট)
  • ডবল স্পষ্টতা ভাসমান বিন্দু সংখ্যা
  • বুলিয়ান
  • স্ট্রিং
  • রূপের ভেক্টর
  • ভেরিয়েন্টে স্ট্রিং এর মানচিত্র

ব্যবহার SetValue() এই ভাবে কোন সন্তান নোড সহ নির্দিষ্ট অবস্থানে ডেটা, মুছে ফেলা হয়। যাইহোক, আপনি এখনও পুরো বস্তুর পুনর্লিখন ছাড়াই একটি শিশুকে আপডেট করতে পারেন। আপনি যদি ব্যবহারকারীদের তাদের প্রোফাইল আপডেট করার অনুমতি দিতে চান তাহলে আপনি নিম্নরূপ ব্যবহারকারীর নাম আপডেট করতে পারেন:

dbref.Child("users").Child(userId).Child("username").SetValue(name);

ডেটার একটি তালিকা যুক্ত করুন

ব্যবহার করুন PushChild() multiuser অ্যাপ্লিকেশন একটি তালিকা ডেটা সংযোজন করতে পদ্ধতি। PushChild() পদ্ধতি একটি অনন্য কী প্রত্যেক সময় একটি নতুন শিশু নিদিষ্ট Firebase রেফারেন্স যোগ করা হয় জেনারেট করে। তালিকার প্রতিটি নতুন উপাদানের জন্য এই স্বয়ংক্রিয়ভাবে তৈরি কীগুলি ব্যবহার করে, বেশ কয়েকজন ক্লায়েন্ট একই সময়ে একই জায়গায় শিশুদের লিখতে দ্বন্দ্ব ছাড়াই যুক্ত করতে পারে। অনন্য দ্বারা উত্পন্ন কী PushChild() , একটি টাইমস্ট্যাম্প উপর ভিত্তি করে, যাতে তালিকা আইটেমগুলি স্বয়ংক্রিয়ভাবে কালানুক্রমে আদেশ হয়।

আপনি দ্বারা ফিরে নতুন তথ্য রেফারেন্স ব্যবহার করতে পারেন PushChild() সন্তানের জন্য সন্তানের স্বয়ংক্রিয়ভাবে তৈরি কী বা সেট ডেটার মান পেতে পদ্ধতি। কলিং GetKey() একটি উপর PushChild() রেফারেন্স স্বয়ংক্রিয়ভাবে তৈরি কী মান ফেরায়।

নির্দিষ্ট ক্ষেত্র আপডেট করুন

একযোগে অন্যান্য শিশু নোড মুছে যাওয়ার ছাড়া একটি নোডের নির্দিষ্ট শিশুদের লিখতে, ব্যবহার UpdateChildren() পদ্ধতি।

যখন কলিং UpdateChildren() , আপনি কী-এর জন্য একটি পাথ নির্দিষ্ট করে নিম্ন পর্যায়ের শিশু মান আপডেট করতে পারেন। তথ্য একাধিক অবস্থান মধ্যে সংরক্ষিত হয় তাহলে ভাল আকার পরিবর্তন করতে, আপনি ব্যবহার যে ডেটা সমস্ত উদাহরণ আপডেট করতে পারেন তথ্য পাখা-আউট । উদাহরণস্বরূপ, একটি খেলা একটি থাকতে পারে 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() যে তথ্য অবস্থানে একটি রেফারেন্সে।

এছাড়াও আপনি একটি নির্দিষ্ট করে মুছে দিতে পারেন null Variant যেমন অন্য লেখ অপারেশন জন্য মান হিসাবে SetValue() বা UpdateChildren() । আপনার সাথে এই কৌশল ব্যবহার করতে পারেন UpdateChildren() একটি একক API কল একাধিক শিশু মুছে দিন।

আপনার ডেটা প্রতিশ্রুতিবদ্ধ হলে জানুন।

যখন আপনার ডেটা Firebase রিয়েলটাইম ডাটাবেজ সার্ভারের করতে প্রতিশ্রুতিবদ্ধ হয় জানতে, চেক ভবিষ্যত সাফল্যের জন্য ফলাফল।

লেনদেন হিসাবে ডেটা সংরক্ষণ করুন

যখন ডেটা আছে যা বৃদ্ধিজনিত কাউন্টারে যেমন সমবর্তী পরিবর্তন, দ্বারা ক্ষতিগ্রস্ত হতে পারে সঙ্গে কাজ, আপনি একটি ব্যবহার করতে পারেন লেনদেন অপারেশন । আপনি এই ক্রিয়াকলাপটি একটি দিতে 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;
  });
}

লেনদেনের ব্যবহার লিডারবোর্ডকে ভুল হতে বাধা দেয় যদি একাধিক ব্যবহারকারী একই সময়ে স্কোর রেকর্ড করে অথবা ক্লায়েন্টের কাছে বাসি ডেটা থাকে। যদি লেনদেন প্রত্যাখ্যান করা হয়, সার্ভার ক্লায়েন্টকে বর্তমান মান ফেরত দেয়, যা আপডেট করা মান দিয়ে আবার লেনদেন চালায়। লেনদেন গ্রহণ না করা পর্যন্ত বা পুনরাবৃত্তি না হওয়া পর্যন্ত অনেক চেষ্টা করা হয়েছে।

অফলাইনে ডেটা লিখুন

যদি কোন ক্লায়েন্ট তার নেটওয়ার্ক সংযোগ হারিয়ে ফেলে, আপনার অ্যাপ সঠিকভাবে কাজ চালিয়ে যাবে।

একটি Firebase ডাটাবেসের সাথে সংযুক্ত প্রতিটি ক্লায়েন্ট যে কোন সক্রিয় ডেটার নিজস্ব অভ্যন্তরীণ সংস্করণ বজায় রাখে। যখন ডেটা লেখা হয়, এটি প্রথমে এই স্থানীয় সংস্করণে লেখা হয়। ফায়ারবেস ক্লায়েন্ট তখন রিমোট ডাটাবেস সার্ভার এবং অন্যান্য ক্লায়েন্টদের সাথে "সেরা-প্রচেষ্টা" ভিত্তিতে সেই ডেটা সিঙ্ক্রোনাইজ করে।

ফলস্বরূপ, সমস্ত ডাটাবেসে লিখলে স্থানীয় ইভেন্টগুলিকে অবিলম্বে ট্রিগার করা হয়, সার্ভারে কোন তথ্য লেখার আগে। এর মানে হল যে আপনার অ্যাপটি নেটওয়ার্ক লেটেন্সি বা কানেক্টিভিটি নির্বিশেষে প্রতিক্রিয়াশীল থাকে।

একবার কানেক্টিভিটি পুনরায় প্রতিষ্ঠিত হয়ে গেলে, আপনার অ্যাপটি ইভেন্টের উপযুক্ত সেট গ্রহণ করে যাতে ক্লায়েন্ট কোন সার্ভার স্টেট এর সাথে সিঙ্ক করে, কোন কাস্টম কোড না লিখে।

পরবর্তী পদক্ষেপ