يتناول هذا المستند أساسيات استرداد البيانات وكيفية ترتيب بيانات 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();
في هذه المرحلة، تم إرسال الطلب ولكن علينا الانتظار إلى أن يكتمل 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 دائمًا عمليات الاسترجاع OnChildChanged OnChildMoved بسبب تغيير ترتيب العناصر (استنادًا إلى طريقة الترتيب الحالية). |
فئة 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<DataSnapshot>
على البيانات المتوفّرة في الموقع الجغرافي المحدّد
في قاعدة البيانات في وقت وقوع الحدث. يؤدي استدعاء 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() |
ترتيب النتائج حسب القيم الفرعية |
يمكنك استخدام طريقة واحدة للترتيب في كل مرة. سيؤدي استدعاء طريقة 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"
القيمة في كل عنصر فرعي. لمزيد من المعلومات حول كيفية ترتيب أنواع البيانات الأخرى، راجِع المقالة كيفية ترتيب بيانات طلبات البحث.
تصفية البيانات
لفلترة البيانات، يمكنك الجمع بين أي من طُرق الحدّ أو النطاق وطريقة order-by عند إنشاء طلب بحث.
الطريقة | الاستخدام |
---|---|
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()
، يتم ترتيب البيانات التي تحتوي على مفتاح العنصر التابع المحدّد على النحو التالي:
- يتم عرض الأطفال الذين لديهم قيمة
null
لمفتاح الطفل المحدّد أولاً. - يأتي بعد ذلك الأطفال الذين لديهم القيمة
false
لمفتاح الطفل المحدّد. إذا كان لدى عدة عناصر فرعية القيمةfalse
، يتم ترتيبها معجميًا حسب المفتاح. - يأتي بعد ذلك الأطفال الذين لديهم القيمة
true
لمفتاح الطفل المحدّد. إذا كان لدى عدة عناصر فرعية القيمةtrue
، يتم ترتيبها معجميًا حسب المفتاح. - تأتي بعد ذلك العناصر الفرعية التي تتضمّن قيمة رقمية، ويتم ترتيبها بترتيب تصاعدي. إذا كان لدى عدة عناصر فرعية القيمة الرقمية نفسها لعقدة الطفل المحدّدة، يتم ترتيبها حسب المفتاح.
- تأتي السلاسل بعد الأرقام ويتم ترتيبها معجميًا بترتيب تصاعدي. إذا كان لدى عدة عناصر فرعية القيمة نفسها لعقدة الطفل المحدّدة، يتم ترتيبها معجميًا حسب المفتاح.
- تأتي الكائنات في النهاية ويتم ترتيبها معجميًا حسب المفتاح بترتيب تصاعدي.
OrderByKey
عند استخدام OrderByKey()
لفرز بياناتك، يتم عرض البيانات بترتيب تصاعدي حسب المفتاح.
- يتم عرض الأطفال الذين لديهم مفتاح يمكن تحليله كعدد صحيح 32 بت أولاً، ويتم ترتيبهم بترتيب تصاعدي.
- يأتي بعد ذلك الأطفال الذين لديهم قيمة سلسلة كمفتاح، ويتم ترتيبهم معجميًا بترتيب تصاعدي.
OrderByValue
عند استخدام OrderByValue()
، يتم ترتيب الأطفال حسب قيمتهم. معايير الترتيب هي نفسها الواردة في OrderByChild()
، باستثناء أنّه يتم استخدام قيمة العقدة بدلاً من قيمة مفتاح ثانوي محدّد.