استرداد البيانات باستخدام قاعدة بيانات Firebase Realtime لـ C++

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

قبل ان تبدأ

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

استرجاع البيانات

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

الحصول على مرجع قاعدة البيانات

لكتابة البيانات إلى قاعدة البيانات، تحتاج إلى مثيل 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::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<firebase::database::DataSnapshot> result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

تحتوي نتيجة Future&ltDataSnapshot&gt على البيانات الموجودة في الموقع المحدد في قاعدة البيانات في وقت الحدث. يؤدي استدعاء value() في لقطة إلى إرجاع Variant يمثل البيانات.

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

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

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

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

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

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

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

فرز البيانات

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

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

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

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

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

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

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

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

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

مع تغير العناصر، تتلقى ردود اتصال 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() ، باستثناء أن قيمة العقدة تُستخدم بدلاً من قيمة المفتاح الفرعي المحدد.

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