C++ এর জন্য ফায়ারবেস রিয়েলটাইম ডেটাবেস দিয়ে ডেটা পুনরুদ্ধার করা হচ্ছে

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

শুরু করার আগে

Get Started গাইডে বর্ণিত নির্দেশনা অনুযায়ী আপনার অ্যাপটি সেটআপ করা হয়েছে এবং আপনি ডেটাবেস অ্যাক্সেস করতে পারছেন, তা নিশ্চিত করুন।

ডেটা পুনরুদ্ধার করা

ফায়ারবেস ডেটা হয় একবার GetValue() কল করে অথবা কোনো FirebaseDatabase রেফারেন্সে ValueListener সংযুক্ত করে পুনরুদ্ধার করা হয়। ডেটার প্রাথমিক অবস্থার জন্য ভ্যালু লিসেনারটি একবার কল করা হয় এবং ডেটা পরিবর্তিত হলেই আবার কল করা হয়।

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

ডেটাবেসে ডেটা লিখতে হলে, আপনার DatabaseReference এর একটি ইনস্ট্যান্স প্রয়োজন।

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

ডেটা একবার পড়ুন

আপনি GetValue() মেথডটি ব্যবহার করে একটি নির্দিষ্ট পাথের বিষয়বস্তুর একটি স্ট্যাটিক স্ন্যাপশট একবার পড়তে পারেন। টাস্কের ফলাফলে সেই অবস্থানের সমস্ত ডেটা, চাইল্ড ডেটা সহ, ধারণকারী একটি স্ন্যাপশট থাকবে। যদি কোনো ডেটা না থাকে, তাহলে ফেরত আসা স্ন্যাপশটটি null হয়।

  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").GetValue();

এই পর্যায়ে অনুরোধটি করা হয়ে গেছে, কিন্তু মানটি পড়ার আগে আমাদের Future-টি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করতে হবে। যেহেতু গেমগুলো সাধারণত একটি লুপের মধ্যে চলে এবং অন্যান্য অ্যাপ্লিকেশনের তুলনায় কম কলব্যাক-নির্ভর, তাই আপনি সাধারণত এর সমাপ্তি জানার জন্য পোলিং করে থাকেন।

  // In the game loop that polls for the result...

  if (result.status() != firebase::kFutureStatusPending) {
    if (result.status() != firebase::kFutureStatusComplete) {
      LogMessage("ERROR: GetValue() returned an invalid result.");
      // Handle the error...
    } else if (result.error() != firebase::database::kErrorNone) {
      LogMessage("ERROR: GetValue() returned error %d: %s", result.error(),
                 result.error_message());
      // Handle the error...
    } else {
      firebase::database::DataSnapshot snapshot = result.result();
      // Do something with the snapshot...
    }
  }

এটি কিছু প্রাথমিক ত্রুটি পরীক্ষা প্রদর্শন করে, ত্রুটি পরীক্ষা এবং ফলাফল কখন প্রস্তুত হবে তা নির্ধারণের উপায় সম্পর্কে আরও তথ্যের জন্য firebase::Future রেফারেন্স দেখুন।

অনুষ্ঠানগুলোর জন্য শুনুন

ডেটার পরিবর্তনে সাবস্ক্রাইব করার জন্য আপনি লিসেনার যোগ করতে পারেন:

ValueListener বেস ক্লাস

কলব্যাক সাধারণ ব্যবহার
OnValueChanged একটি পাথের সম্পূর্ণ বিষয়বস্তুর পরিবর্তনগুলো পড়ুন এবং শুনুন।

OnChildListener বেস ক্লাস

OnChildAdded আইটেমের তালিকা পুনরুদ্ধার করুন অথবা তালিকায় নতুন সংযোজনের জন্য নজর রাখুন। তালিকার পরিবর্তন নিরীক্ষণের জন্য OnChildChanged এবং OnChildRemoved সাথে এটি ব্যবহারের পরামর্শ দেওয়া হয়।
OnChildChanged একটি তালিকার আইটেমগুলির পরিবর্তন পর্যবেক্ষণ করুন। তালিকার পরিবর্তন নিরীক্ষণ করতে OnChildAdded এবং OnChildRemoved সাথে এটি ব্যবহার করুন।
OnChildRemoved তালিকা থেকে কোনো আইটেম মুছে ফেলার বিষয়টি পর্যবেক্ষণ করুন। তালিকার পরিবর্তন নিরীক্ষণ করতে OnChildAdded এবং OnChildChanged সাথে এটি ব্যবহার করুন।
OnChildMoved একটি অর্ডারড লিস্টে আইটেমগুলোর ক্রম পরিবর্তনের জন্য নজর রাখুন। আইটেমের ক্রম পরিবর্তনের কারণে (আপনার বর্তমান অর্ডার-বাই পদ্ধতির উপর ভিত্তি করে) OnChildMoved কলব্যাকগুলো সর্বদা OnChildChanged কলব্যাকগুলোর পরে আসে।

ভ্যালুলিসেনার ক্লাস

আপনি একটি নির্দিষ্ট পাথের বিষয়বস্তুর পরিবর্তনে সাবস্ক্রাইব করতে OnValueChanged কলব্যাকগুলো ব্যবহার করতে পারেন। এই কলব্যাকটি লিসেনার সংযুক্ত হওয়ার সময় একবার এবং চাইল্ড ডেটা সহ প্রতিবার ডেটা পরিবর্তিত হলে আবার ট্রিগার হয়। কলব্যাকটিতে একটি স্ন্যাপশট পাঠানো হয়, যাতে চাইল্ড ডেটা সহ সেই অবস্থানের সমস্ত ডেটা থাকে। যদি কোনো ডেটা না থাকে, তাহলে ফেরত আসা স্ন্যাপশটটি null হয়।

নিম্নলিখিত উদাহরণটি ডাটাবেস থেকে লিডারবোর্ডের স্কোর পুনরুদ্ধার করার একটি গেম প্রদর্শন করে:

  class LeadersValueListener : public firebase::database::ValueListener {
   public:
    void OnValueChanged(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: LeadersValueListener canceled: %d: %s", error_code,
                 error_message);
    }
  };

  // Elsewhere in the code...

  LeadersValueListener* listener = new LeadersValueListener();
  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

Future&ltDataSnapshot&gt ফলাফলে ইভেন্টটি ঘটার সময় ডাটাবেসের নির্দিষ্ট অবস্থানে থাকা ডেটা থাকে। একটি স্ন্যাপশটের উপর value() কল করলে ডেটাটির প্রতিনিধিত্বকারী একটি Variant ফেরত আসে।

এই উদাহরণে, রিডটি বাতিল করা হয়েছে কিনা তা দেখার জন্য OnCancelled মেথডটিও ওভাররাইড করা হয়েছে। উদাহরণস্বরূপ, কোনো ক্লায়েন্টের যদি ফায়ারবেস ডাটাবেস লোকেশন থেকে রিড করার অনুমতি না থাকে, তাহলে একটি রিড বাতিল করা হতে পারে। database::Error মেথডটি ব্যর্থতার কারণ নির্দেশ করবে।

চাইল্ডলিসেনার ক্লাস

কোনো নোডের চাইল্ডদের উপর নির্দিষ্ট কিছু অপারেশনের প্রতিক্রিয়ায় চাইল্ড ইভেন্টগুলো ট্রিগার হয়। যেমন, PushChild() মেথডের মাধ্যমে একটি নতুন চাইল্ড যোগ করা অথবা UpdateChildren() মেথডের মাধ্যমে একটি চাইল্ডকে আপডেট করা। এগুলোর প্রত্যেকটি একসাথে একটি ডাটাবেসের নির্দিষ্ট নোডের পরিবর্তনগুলো শোনার জন্য কার্যকর হতে পারে। উদাহরণস্বরূপ, একটি গেম এই মেথডগুলো একসাথে ব্যবহার করে একটি গেম সেশনের কমেন্টগুলোর কার্যকলাপ পর্যবেক্ষণ করতে পারে, যেমনটি নিচে দেখানো হয়েছে:

  class SessionCommentsChildListener : public firebase::database::ChildListener {
   public:
    void OnChildAdded(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildChanged(const firebase::database::DataSnapshot& snapshot,
                        const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildRemoved(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot ...
    }
    void OnChildMoved(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: SessionCommentsChildListener canceled: %d: %s",
                 error_code, error_message);
    }
  };

  // elsewhere ....

  SessionCommentsChildListener* listener = new SessionCommentsChildListener();
  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

OnChildAdded কলব্যাকটি সাধারণত ফায়ারবেস ডাটাবেসের আইটেমগুলির একটি তালিকা পুনরুদ্ধার করতে ব্যবহৃত হয়। প্রতিটি বিদ্যমান চাইল্ডের জন্য OnChildAdded কলব্যাকটি একবার কল করা হয় এবং তারপরে নির্দিষ্ট পাথে যখনই একটি নতুন চাইল্ড যুক্ত করা হয়, তখন এটি আবার কল করা হয়। লিসেনারকে নতুন চাইল্ডের ডেটা সম্বলিত একটি স্ন্যাপশট পাস করা হয়।

যখনই কোনো চাইল্ড নোড পরিবর্তিত হয়, তখনই OnChildChanged কলব্যাকটি কল করা হয়। এর মধ্যে চাইল্ড নোডের বংশধরদের যেকোনো পরিবর্তনও অন্তর্ভুক্ত। আইটেমের তালিকার পরিবর্তনে সাড়া দেওয়ার জন্য এটি সাধারণত OnChildAdded এবং OnChildRemoved কলগুলোর সাথে একত্রে ব্যবহৃত হয়। লিসেনারে পাঠানো স্ন্যাপশটটিতে চাইল্ডের জন্য আপডেট করা ডেটা থাকে।

যখন কোনো নিকটবর্তী চাইল্ডকে সরিয়ে দেওয়া হয়, তখন OnChildRemoved কলব্যাকটি ট্রিগার হয়। এটি সাধারণত OnChildAdded এবং OnChildChanged কলব্যাকগুলোর সাথে একত্রে ব্যবহৃত হয়। কলব্যাকে পাঠানো স্ন্যাপশটটিতে সরিয়ে দেওয়া চাইল্ডটির ডেটা থাকে।

যখনই কোনো আপডেটের কারণে চাইল্ডের ক্রম পরিবর্তন হয় এবং OnChildChanged কলটি উত্থাপিত হয়, তখন OnChildMoved কলব্যাকটি ট্রিগার হয়। এটি OrderByChild বা OrderByValue পদ্ধতিতে সাজানো ডেটার ক্ষেত্রে ব্যবহৃত হয়।

ডেটা সাজানো এবং ফিল্টার করা

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

ডেটা সাজান

সাজানো ডেটা পেতে, ফলাফল কীভাবে সাজানো হবে তা নির্ধারণ করতে প্রথমে order-by পদ্ধতিগুলোর মধ্যে একটি নির্দিষ্ট করুন:

পদ্ধতি ব্যবহার
OrderByChild() একটি নির্দিষ্ট চাইল্ড কী-এর মান অনুসারে ফলাফলগুলো সাজান।
OrderByKey() চাইল্ড কী অনুসারে ফলাফলগুলো সাজান।
OrderByValue() চাইল্ড ভ্যালু অনুসারে ফলাফলগুলো সাজান।

আপনি একবারে শুধুমাত্র একটি order-by মেথড ব্যবহার করতে পারবেন। একই কোয়েরিতে একাধিকবার order-by মেথড কল করলে একটি এরর দেখা দেয়।

নিম্নলিখিত উদাহরণটি দেখায় যে আপনি কীভাবে স্কোর অনুসারে সাজানো একটি স্কোর লিডারবোর্ডে সাবস্ক্রাইব করতে পারেন।

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score");

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

এটি একটি firebase::Query সংজ্ঞায়িত করে, যা একটি ValueListener-এর সাথে মিলিত হয়ে ক্লায়েন্টকে ডাটাবেসের লিডারবোর্ডের সাথে সিঙ্ক্রোনাইজ করে এবং প্রতিটি এন্ট্রির স্কোর অনুসারে সাজিয়ে রাখে। আপনার ডেটা দক্ষতার সাথে গঠন করার বিষয়ে আরও জানতে, আপনি "আপনার ডাটাবেস গঠন করুন" অংশটি পড়তে পারেন।

OrderByChild() মেথডটি কল করার মাধ্যমে কোন চাইল্ড কী-এর ভিত্তিতে ফলাফল সাজানো হবে তা নির্দিষ্ট করা হয়। এক্ষেত্রে, প্রতিটি চাইল্ডের "score" ভ্যালুর মান অনুসারে ফলাফল সাজানো হয়। অন্যান্য ডেটা টাইপ কীভাবে সাজানো হয় সে সম্পর্কে আরও তথ্যের জন্য, "How query data is ordered" দেখুন।

ডেটা ফিল্টার করা

কোয়েরি তৈরি করার সময় ডেটা ফিল্টার করতে আপনি limit বা range মেথডের যেকোনোটির সাথে order-by মেথড ব্যবহার করতে পারেন।

পদ্ধতি ব্যবহার
LimitToFirst() ফলাফলের ক্রমিক তালিকার শুরু থেকে ফেরত দেওয়া আইটেমের সর্বোচ্চ সংখ্যা নির্ধারণ করে।
LimitToLast() ফলাফলের ক্রমিক তালিকার শেষ থেকে ফেরত দেওয়া আইটেমের সর্বোচ্চ সংখ্যা নির্ধারণ করে।
StartAt() নির্বাচিত অর্ডার-বাই পদ্ধতির উপর নির্ভর করে, নির্দিষ্ট কী বা মানের সমান বা তার চেয়ে বড় আইটেমগুলো ফেরত দেওয়া হবে।
EndAt() নির্বাচিত অর্ডার-বাই পদ্ধতির উপর নির্ভর করে, নির্দিষ্ট কী বা মানের সমান বা তার চেয়ে কম আইটেমগুলো ফেরত দেওয়া হবে।
EqualTo() নির্বাচিত অর্ডার-বাই পদ্ধতির উপর নির্ভর করে নির্দিষ্ট কী বা ভ্যালুর সমান আইটেমগুলো ফেরত দিন।

অর্ডার-বাই মেথডগুলোর থেকে ভিন্নভাবে, আপনি একাধিক লিমিট বা রেঞ্জ ফাংশন একত্রিত করতে পারেন। উদাহরণস্বরূপ, ফলাফলকে একটি নির্দিষ্ট পরিসরের মধ্যে সীমাবদ্ধ করতে আপনি StartAt() এবং EndAt() মেথড দুটিকে একত্রিত করতে পারেন।

এমনকি কোয়েরির জন্য মাত্র একটি মিল থাকলেও, স্ন্যাপশটটি একটি তালিকাই থাকে; এতে শুধু একটি আইটেম থাকে।

ফলাফলের সংখ্যা সীমিত করুন

আপনি একটি নির্দিষ্ট কলব্যাকের জন্য সিঙ্ক করা চাইল্ডের সর্বোচ্চ সংখ্যা নির্ধারণ করতে LimitToFirst() এবং LimitToLast() মেথডগুলো ব্যবহার করতে পারেন। উদাহরণস্বরূপ, যদি আপনি LimitToFirst() ব্যবহার করে ১০০-এর একটি সীমা নির্ধারণ করেন, তাহলে আপনি প্রাথমিকভাবে সর্বোচ্চ ১০০টি OnChildAdded কলব্যাক পাবেন। যদি আপনার Firebase ডেটাবেসে ১০০টির কম আইটেম সংরক্ষিত থাকে, তাহলে প্রতিটি আইটেমের জন্য একটি করে OnChildAdded কলব্যাক চালু হবে।

আইটেম পরিবর্তন হওয়ার সাথে সাথে, কোয়েরিতে নতুন যুক্ত হওয়া আইটেমগুলোর জন্য আপনি OnChildAdded কলব্যাক এবং কোয়েরি থেকে বাদ পড়া আইটেমগুলোর জন্য OnChildRemoved কলব্যাক পাবেন, যাতে মোট সংখ্যা ১০০-তেই স্থির থাকে।

উদাহরণস্বরূপ, নিচের কোডটি একটি লিডারবোর্ড থেকে সর্বোচ্চ স্কোরটি ফেরত দেয়:

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score").LimitToLast(1);

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

কী বা ভ্যালু দ্বারা ফিল্টার করুন

আপনি কোয়েরির জন্য ইচ্ছামতো শুরু, শেষ এবং সমতুল্য বিন্দু বেছে নিতে StartAt() , EndAt() , এবং EqualTo() ব্যবহার করতে পারেন। ডেটা পেজিনেট করতে অথবা নির্দিষ্ট মানের চাইল্ড আইটেম আছে এমন আইটেম খুঁজে বের করতে এটি কার্যকর হতে পারে।

কোয়েরি ডেটা কীভাবে সাজানো হয়

এই অংশে Query ক্লাসের প্রতিটি order-by মেথড ব্যবহার করে কীভাবে ডেটা সর্ট করা হয় তা ব্যাখ্যা করা হয়েছে।

OrderByChild

OrderByChild() ব্যবহার করার সময়, নির্দিষ্ট চাইল্ড কী ধারণকারী ডেটা নিম্নলিখিতভাবে সাজানো হয়:

  1. নির্দিষ্ট চাইল্ড কী-এর মান null হলে চাইল্ডগুলো প্রথমে আসে।
  2. নির্দিষ্ট চাইল্ড কী-এর জন্য যেসব চাইল্ডের মান false , সেগুলো এরপরে আসে। যদি একাধিক চাইল্ডের মান false হয়, তবে সেগুলোকে কী অনুসারে আভিধানিকভাবে সাজানো হয়।
  3. নির্দিষ্ট চাইল্ড কী-এর মান ' true হলে চাইল্ডগুলো এরপরে আসে। যদি একাধিক চাইল্ডের মান ' true হয়, তবে সেগুলোকে কী অনুসারে আভিধানিকভাবে সাজানো হয়।
  4. সাংখ্যিক মানযুক্ত চাইল্ডগুলো এরপর আরোহী ক্রমে আসে। যদি নির্দিষ্ট চাইল্ড নোডটির জন্য একাধিক চাইল্ডের একই সাংখ্যিক মান থাকে, তবে সেগুলোকে কী (key) অনুসারে সাজানো হয়।
  5. সংখ্যার পরে স্ট্রিংগুলো আসে এবং আভিধানিকভাবে আরোহী ক্রমে সাজানো হয়। যদি নির্দিষ্ট চাইল্ড নোডের জন্য একাধিক চাইল্ডের একই মান থাকে, তবে সেগুলোকে কী (key) অনুসারে আভিধানিকভাবে সাজানো হয়।
  6. বস্তুগুলো শেষে আসে এবং চাবি অনুসারে আভিধানিকভাবে আরোহী ক্রমে সাজানো হয়।

OrderByKey

OrderByKey() ব্যবহার করে ডেটা সর্ট করার সময়, ডেটা কী (key) অনুসারে আরোহী ক্রমে ফেরত আসে।

  1. যেসব চাইল্ডের কী-কে ৩২-বিট পূর্ণসংখ্যা হিসেবে পার্স করা যায়, সেগুলো আরোহী ক্রমে প্রথমে আসে।
  2. যেসব চাইল্ডের কী (key) হিসেবে স্ট্রিং ভ্যালু রয়েছে, সেগুলো আভিধানিকভাবে আরোহী ক্রমে সাজানো অবস্থায় এরপরে আসে।

OrderByValue

OrderByValue() ব্যবহার করার সময়, চাইল্ড নোডগুলো তাদের ভ্যালু অনুসারে সাজানো হয়। সাজানোর মানদণ্ড OrderByChild() এর মতোই, তবে এক্ষেত্রে একটি নির্দিষ্ট চাইল্ড কী-এর ভ্যালুর পরিবর্তে নোডটির ভ্যালু ব্যবহৃত হয়।

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