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

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

قبل البدء

لاستخدام Realtime Database، عليك إجراء ما يلي:

  • سجِّل مشروعك على Unity واضبطه لاستخدام Firebase.

    • إذا كان مشروعك على Unity يستخدم Firebase، يعني ذلك أنّه سبق تسجيله وإعداده لاستخدام Firebase.

    • إذا لم يكن لديك مشروع Unity، يمكنك تنزيل نموذج تطبيق.

  • أضِف Firebase حزمة تطوير البرامج (SDK) Unity (على وجه التحديد، FirebaseDatabase.unitypackage) إلى مشروعك على Unity.

تجدر الإشارة إلى أنّ إضافة Firebase إلى مشروعك على Unity تتضمن مهامًا في كلّ من وحدة تحكّم Firebase ومشروع Unity المفتوح (على سبيل المثال، يمكنك تنزيل ملفات إعدادات Firebase من وحدة التحكّم، ثم نقلها إلى مشروع Unity).

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

يتم استرداد بيانات Firebase إما من خلال طلب لمرة واحدة إلى GetValueAsync()‎ أو الربط بحدث في مرجع FirebaseDatabase. يتم استدعاء مستمع الأحداث مرة واحدة للحالة الأولية للبيانات ومرة أخرى في أي وقت تتغيّر فيه البيانات.

الحصول على DatabaseReference

لقراءة البيانات من قاعدة البيانات، تحتاج إلى مثيل من DatabaseReference:

using Firebase;
using Firebase.Database;
using Firebase.Extensions.TaskExtension; // for ContinueWithOnMainThread

public class MyScript: MonoBehaviour {
  void Start() {
    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

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

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

    FirebaseDatabase.DefaultInstance
      .GetReference("Leaders")
      .GetValueAsync().ContinueWithOnMainThread(task =&gt {
        if (task.IsFaulted) {
          // Handle the error...
        }
        else if (task.IsCompleted) {
          DataSnapshot snapshot = task.Result;
          // Do something with snapshot...
        }
      });

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

يمكنك إضافة أدوات معالجة الأحداث للاشتراك في التغييرات التي تطرأ على البيانات:

الحدث الاستخدام المعتاد
ValueChanged قراءة التغييرات في محتوى مسار معيّن والاستماع إليها
ChildAdded استرداد قوائم بالعناصر أو الاستماع إلى الإضافات إلى قائمة بالعناصر الاستخدام المقترَح مع ChildChanged و ChildRemoved لرصد التغييرات في القوائم
ChildChanged رصد التغييرات على العناصر في القائمة استخدِم رمزَي ChildAdded وChildRemoved لرصد التغييرات في القوائم.
ChildRemoved رصد العناصر التي تتم إزالتها من القائمة استخدِم رمزَي ChildAdded وChildChanged لرصد التغييرات في القوائم.
ChildMoved استمع إلى التغييرات في ترتيب العناصر في قائمة مرتبة. تتبع أحداث ChildMoved دائمًا حدث ChildChanged الذي أدّى إلى تغيير ترتيب السلعة (استنادًا إلى طريقة الترتيب الحالية).

حدث ValueChanged

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

بإرفاق مستمع أحداث بجذر قاعدة بياناتك.

يوضّح المثال التالي لعبة تسترجع نتائج قائمة صدارة من قاعدة البيانات:

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

يحتوي ValueChangedEventArgs على DataSnapshot يحتوي على البيانات في الموقع المحدّد في قاعدة البيانات في وقت الحدث. يؤدي استدعاء Value على لقطة بيانات إلى عرض Dictionary<string, object> يمثّل البيانات. وفي حال عدم توفّر بيانات في الموقع الجغرافي، يعرض الاتصال بـ Value القيمة null.

في هذا المثال، يتم أيضًا فحص args.DatabaseError لمعرفة ما إذا تم إلغاء القراءة. على سبيل المثال، يمكن إلغاء عملية قراءة إذا لم يكن لدى العميل إذن بالقراءة من موقع بيانات قاعدة بيانات Firebase. سيشير الرمز DatabaseError إلى سبب تعذُّر إكمال العملية.

ويمكنك لاحقًا إلغاء الاشتراك في الحدث باستخدام أي DatabaseReference يحتوي على المسار نفسه. تكون نُسخ DatabaseReference مؤقتة ويمكن اعتبارها كطريقة للوصول إلى أي مسار وطلب بحث.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged -= HandleValueChanged; // unsubscribe from ValueChanged.
    }

الأحداث الخاصة بالأطفال

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

      var ref = FirebaseDatabase.DefaultInstance
      .GetReference("GameSessionComments");

      ref.ChildAdded += HandleChildAdded;
      ref.ChildChanged += HandleChildChanged;
      ref.ChildRemoved += HandleChildRemoved;
      ref.ChildMoved += HandleChildMoved;
    }

    void HandleChildAdded(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildChanged(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildRemoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildMoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

ويُستخدَم حدث ChildAdded عادةً لاسترداد قائمة بالعناصر في قاعدة بيانات Firebase. يتمّ تنشيط الحدث ChildAdded مرة واحدة لكلّ عنصر فرعي حالي، ثمّ مرة أخرى في كلّ مرّة تتمّ فيها إضافة عنصر فرعي جديد إلى المسار المحدّد. يتم تمرير لقطة تحتوي على data الطفل الجديد إلى المستمع.

يتمّ تنشيط الحدث ChildChanged في أيّ وقت يتمّ فيه تعديل عقدة فرعية. ويشمل ذلك أي تعديلات على العناصر الفرعية للعقدة الفرعية. ويُستخدَم عادةً مع حدثَي ChildAdded وChildRemoved للاستجابة للتغييرات التي تطرأ على قائمة العناصر. تحتوي اللقطة التي يتم تمريرها إلى مستمع الحدث على البيانات المحدثة للطفل.

يتم بدء الحدث ChildRemoved عند إزالة عنصر فرعي مباشر. ويُستخدَم عادةً مع وظيفتَي الاستدعاء ChildAdded و ChildChanged. تحتوي اللقطة التي تم تمريرها إلى دالة الاستدعاء للحدث على بيانات الطفل الذي تمّت إزالته.

يتم بدء الحدث ChildMoved عند حدوث الحدث ChildChanged نتيجة تحديث يؤدي إلى إعادة ترتيب العنصر الفرعي. ويتم استخدامها مع البيانات التي يتم ترتيبها باستخدام OrderByChild أو OrderByValue.

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

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

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

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

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

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

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

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

يحدِّد هذا الطلب بحثًا يتم من خلاله عند دمجه مع مستمع حدث valuechanged مزامنة العميل مع قائمة الصدارة في قاعدة البيانات، مرتَّبة حسب النتيجة لكل إدخال. يمكنك الاطّلاع على مزيد من المعلومات حول تنظيم بياناتك بكفاءة في مقالة تنظيم قاعدة بياناتك.

تحدِّد الدعوة إلى الطريقة OrderByChild() مفتاح الطفل لترتيب النتائج. في هذه الحالة، يتم ترتيب النتائج حسب قيمة القيمة "score" في كل عنصر فرعي. لمزيد من المعلومات عن كيفية ترتيب أنواع البيانات الأخرى، اطّلِع على كيفية ترتيب بيانات طلبات البحث.

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

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

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

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

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

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

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

عندما تتغيّر العناصر، تتلقّى ChildAdded طلب استدعاء للعناصر التي تدخل في طلب البحث وChildRemoved طلب استدعاء للعناصر التي تخرج منه كي يظل إجمالي العدد 100.

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

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score").LimitToLast(1)
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

الفلترة حسب المفتاح أو القيمة

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