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

فئة 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&ltDataSnaphot&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 . تحتوي اللقطة التي تم تمريرها إلى رد الاتصال على بيانات الطفل الذي تمت إزالته.

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

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

يمكنك استخدام فئة Realtime Database 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() ، فيما عدا قيمة العقدة المستخدمة بدلاً من قيمة المفتاح الفرعي المحدد.

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