استرداد البيانات باستخدام قاعدة بيانات Firebase في الوقت الفعلي للغة C++

يتناول هذا المستند أساسيات استرداد البيانات وكيفية الترتيب والتصفية بيانات Firebase.

قبل البدء

تأكَّد من إعداد تطبيقك وإمكانية الوصول إلى قاعدة البيانات على النحو الموضّح في دليل Get Started.

استرداد البيانات

يتم استرداد بيانات Firebase إما من خلال استدعاء لمرة واحدة إلى GetValue() أو إرفاقها بـ ValueListener في مرجع FirebaseDatabase. القيمة يتم استدعاء المستمع مرة واحدة للحالة الأولية للبيانات ومرة أخرى في أي وقت التغييرات في البيانات.

الحصول على DatabaseReference

لكتابة بيانات إلى قاعدة البيانات، أنت بحاجة إلى نسخة افتراضية من DatabaseReference:

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

قراءة البيانات مرة واحدة

ويمكنك استخدام الطريقة GetValue() لقراءة نبذة ثابتة عن والمحتوى في مسار معين مرة واحدة. ستتضمّن نتيجة المهمة لقطة ملف شخصي تحتوي على جميع البيانات في ذلك الموقع الجغرافي، بما في ذلك بيانات الأطفال. في حال عدم توفّر بيانات، تكون الصورة المصغّرة المعروضة هي null.

  firebase::Future<firebase::database::DataSnapshot> result =
    dbRef.GetReference("Leaders").GetValue();

عند تقديم الطلب، علينا الانتظار إلى أن كاملة قبل أن نتمكن من قراءة القيمة. نظرًا لأن الألعاب تعمل عادةً بشكل متكرر، تعتمد على معاودة الاتصال بشكل أقل من التطبيقات الأخرى، فستقوم عادةً باستطلاع إتمام المشروع.

  // 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::المستقبل ومعلومات حول التحقق من الأخطاء وطرق تحديد متى تكون النتيجة جاهزة.

الاستماع إلى الأحداث

يمكنك إضافة مستمعين للاشتراك في التغييرات التي تطرأ على البيانات:

ValueListener فئة أساسية

رد الاتصال معدّل الاستخدام
OnValueChanged قراءة التغييرات التي تتم على محتوى المسار بالكامل والاستماع إليها

OnChildListener فئة أساسية

OnChildAdded استرداد قوائم بالعناصر أو الاستماع إلى الإضافات إلى قائمة بالعناصر الاستخدام المقترَح مع OnChildChanged و OnChildRemoved لرصد التغييرات في القوائم
OnChildChanged الاستماع إلى التغييرات في العناصر ضمن قائمة الاستخدام مع OnChildAdded وOnChildRemoved للمراقبة التغييرات على القوائم.
OnChildRemoved استمع إلى العناصر التي تتم إزالتها من قائمة. الاستخدام مع OnChildAdded وOnChildChanged للمراقبة التغييرات على القوائم.
OnChildMoved استمع إلى التغييرات في ترتيب العناصر في قائمة مرتبة. تتّبع OnChildMoved استدعاءات دائمًا OnChildChanged طلبات معاودة الاتصال بسبب طلب العنصر تغيير (استنادًا إلى طريقة الترتيب الحالية).

فئة ValueListener

يمكنك استخدام استدعاءات 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<firebase::database::DataSnapshot> result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

تحتوي نتيجة Future&ltDataSnapshot&gt على البيانات في الموقع المحدد في قاعدة البيانات في وقت الحدث. جارٍ الاتصال بالرقم value() من أجل الحصول على نبذة ينتج عنها Variant التي تمثل البيانات.

في هذا المثال، يتم أيضًا إلغاء طريقة OnCancelled لمعرفة ما إذا كانت قراءة تم إلغاؤه. على سبيل المثال، يمكن إلغاء القراءة إذا لم يكن لدى العميل إذن للقراءة من موقع قاعدة بيانات Firebase. سيشير database::Error إلى سبب حدوث الخطأ.

فئة ChildListener

يتم تشغيل الأحداث الفرعية استجابةً لعمليات محددة تحدث في العناصر الثانوية لعقدة من أي عملية، مثل إضافة عنصر ثانوي جديد من خلال طريقة 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<firebase::database::DataSnapshot> result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

يتم عادةً استخدام استدعاء OnChildAdded لاسترداد قائمة العناصر في قاعدة بيانات Firebase. يتم استدعاء دالة معاودة الاتصال OnChildAdded مرة واحدة لكل طفل حالي ثم مرة أخرى في كل مرة تتم فيها إضافة طفل جديد إلى المسار المحدد. يتم السماح للمستمِع بأخذ لقطة تحتوي على الطفل الجديد البيانات.

يتمّ استدعاء دالة الاستدعاء OnChildChanged في أيّ وقت يتمّ فيه تعديل عقدة فرعية. يتضمن ذلك أي تعديلات على العناصر التابعة للعقدة الفرعية. ويُستخدَم عادةً مع OnChildAdded وOnChildRemoved للردّ على التغييرات في قائمة العناصر. تم تمرير اللقطة إلى يحتوي المستمع على البيانات المحدثة الخاصة بالطفل.

يتمّ تشغيل دالة الاستدعاء OnChildRemoved عند إزالة عنصر فرعي مباشر. ويُستخدَم عادةً مع وظيفتَي الاستدعاء OnChildAdded و OnChildChanged. تحتوي اللقطة التي تم تمريرها إلى دالة الاستدعاء على data الخاصة بالطفل الذي تمّت إزالته.

يتم تشغيل استدعاء OnChildMoved عند استخدام OnChildChanged عن طريق تحديث يؤدي إلى إعادة ترتيب الطفل. من المهم مع البيانات المطلوبة باستخدام OrderByChild أو OrderByValue.

فرز البيانات وتصفيتها

يمكنك استخدام الفئة Query التي تتضمّن Realtime Database لاسترداد بيانات مرتّبة حسب. مفتاح أو حسب القيمة أو حسب القيمة الفرعية. يمكنك أيضًا فلترة النتيجة التي تم فرزها إلى عدد محدد من النتائج أو مجموعة من المفاتيح أو القيم.

ترتيب البيانات

لاسترداد البيانات التي تم فرزها، ابدأ بتحديد إحدى طرق الترتيب حسب لتحديد كيفية ترتيب النتائج:

الطريقة الاستخدام
OrderByChild() يمكنك ترتيب النتائج حسب قيمة مفتاح فرعي محدّد.
OrderByKey() ترتيب النتائج حسب مفاتيح العناصر الفرعية
OrderByValue() ترتيب النتائج حسب قيم السمات الثانوية

يمكنك استخدام طريقة واحدة فقط لترتيب النتائج في كل مرة. يؤدي استدعاء طريقة ترتيب بالاستناد إلى عمود معيّن مرارًا وتكرارًا في طلب البحث نفسه إلى ظهور خطأ.

يوضّح المثال التالي كيفية الاشتراك في قائمة صدارة تهدف إلى قياس الأداء بالاستناد إلى النتيجة.

  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" في كل عنصر فرعي. لمزيد من المعلومات عن كيفية ترتيب أنواع البيانات الأخرى، اطّلِع على كيفية ترتيب بيانات طلبات البحث.

تصفية البيانات

لفلترة البيانات، يمكنك دمج أيّ من طرق الحدّ أو النطاق مع طريقة order-by عند إنشاء طلب بحث.

الطريقة الاستخدام
LimitToFirst() لتعيين الحد الأقصى لعدد العناصر المراد عرضها من بداية قائمة نتائج مرتبة.
LimitToLast() لضبط الحد الأقصى لعدد السلع المطلوب عرضها من نهاية طلب الشراء قائمة بالنتائج.
StartAt() عرض العناصر التي تكون أكبر من أو تساوي المفتاح أو القيمة المحدّدة استنادًا إلى طريقة الترتيب المحدّدة
EndAt() عرض العناصر التي تكون قيمتها أقل من أو مساوية للمفتاح أو القيمة المحدّدة استنادًا إلى طريقة الترتيب المحدّدة
EqualTo() إرجاع عناصر مساوية للمفتاح أو القيمة المحددة اعتمادًا على الطريقة المختارة.

على عكس طرق الترتيب حسب، يمكنك الجمع بين دوال متعددة للحدود أو النطاقات. على سبيل المثال، يمكنك دمج الطريقتَين StartAt() وEndAt() للحدّ من النتائج إلى نطاق محدّد من القيم.

وحتى في حالة وجود مطابقة واحدة فقط لطلب البحث، فستظل اللقطة قائمة فإنها تحتوي فقط على عنصر واحد.

تحديد عدد النتائج

يمكنك استخدام الطريقتَين LimitToFirst() وLimitToLast() لضبط الحد الأقصى لعدد العناصر الثانوية المطلوب مزامنتها لمعاودة اتصال معيّنة. على سبيل المثال، إذا كنت تستخدم LimitToFirst() لضبط حد أقصى يبلغ 100، لن تتلقّى في البداية سوى ما يصل إلى 100 مكالمة OnChildAdded. إذا كان لديك أقل من 100 عنصر مخزّن في قاعدة بيانات Firebase، يتمّ تشغيل OnChildAdded callback لكلّ عنصر.

ومع تغيُّر العناصر، ستتلقّى OnChildAdded عمليات معاودة الاتصال للعناصر التي تدخل في وOnChildRemoved عمليات استدعاء للعناصر التي تستخرج منها بحيث يظل العدد الإجمالي 100.

على سبيل المثال، يعرض الرمز أدناه أعلى نتيجة من قائمة الصدارة:

  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.

OrderByChild

عند استخدام OrderByChild()، يتم ترتيب البيانات التي تحتوي على مفتاح فرعي محدّد على النحو التالي:

  1. تظهر أولاً العناصر الفرعية التي تحتوي على قيمة null لمفتاح العنصر الفرعي المحدّد.
  2. تأتي بعد ذلك العناصر الفرعية التي تحتوي على قيمة false لمفتاح العنصر الفرعي المحدّد. إذا كانت القيمة false للعديد من العناصر الثانوية، يتم تمثيلها مرتبة معجميًا حسب المفتاح.
  3. تأتي بعد ذلك العناصر الفرعية التي تحتوي على قيمة true لمفتاح العنصر الفرعي المحدّد. إذا كانت قيمة عناصر فرعية متعددة هي true، يتم ترتيبها أبجديًا حسب المفتاح.
  4. تأتي العناصر الفرعية التي تحتوي على قيمة رقمية بعد ذلك، ويتم ترتيبها تصاعديًا. إذا كانت عدّة عناصر فرعية لها القيمة الرقمية نفسها لعنصر فرعي محدّد، يتم ترتيبها حسب المفتاح.
  5. تأتي السلاسل بعد الأرقام ويتم ترتيبها بشكل قاموس تصاعديًا. طلبك. إذا كانت هناك عدة عناصر ثانوية لها نفس القيمة للعنصر الفرعي المحدد يتم ترتيبها قاموسًا حسب المفتاح.
  6. تظهر العناصر في آخر القائمة ويتم ترتيبها أبجديًا حسب المفتاح بترتيب تصاعدي.

OrderByKey

عند استخدام OrderByKey() لترتيب بياناتك، يتم عرض البيانات تصاعديًا. بالمفتاح.

  1. تأتي العناصر الثانوية التي تتضمن مفتاحًا يمكن تحليله كعدد صحيح 32 بت أولاً، ويتم ترتيبها تصاعديًا.
  2. يأتي العناصر الثانوية التي لها قيمة سلسلة كمفتاحها بعد ذلك، ويتم فرزها ترتيبًا تصاعديًا.

OrderByValue

عند استخدام OrderByValue()، يتم ترتيب العناصر الثانوية حسب قيمتها. ترتيب هذه المعايير هي نفسها في OrderByChild()، باستثناء قيمة العقدة يتم استخدامه بدلاً من قيمة مفتاح فرعي محدد.

الخطوات التالية