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

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

قبل ان تبدأ

قبل أن تتمكن من استخدام Realtime Database ، تحتاج إلى:

  • سجل مشروع Unity الخاص بك وقم بتكوينه لاستخدام Firebase.

    • إذا كان مشروع Unity الخاص بك يستخدم Firebase بالفعل ، فهذا يعني أنه تم تسجيله بالفعل وتهيئته لـ Firebase.

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

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

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

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

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

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

لقراءة البيانات من قاعدة البيانات ، تحتاج إلى مثيل 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 => {
        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 مرة واحدة لكل طفل موجود ثم مرة أخرى في كل مرة يتم فيها إضافة طفل جديد إلى المسار المحدد. يمرر المستمع لقطة تحتوي على بيانات الطفل الجديد.

يتم تشغيل الحدث 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
    }

يحدد هذا الاستعلام أنه عند دمجه مع مستمع حدث ذي قيمة ، يقوم بمزامنة العميل مع لوحة الصدارة في قاعدة البيانات ، مرتبة حسب درجة كل إدخال. يمكنك قراءة المزيد حول هيكلة بياناتك بكفاءة في هيكلة قاعدة البيانات الخاصة بك .

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

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

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

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

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

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

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

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

عندما تتغير العناصر ، تتلقى عمليات رد نداء ChildAdded للعناصر التي تدخل الاستعلام و ChildRemoved Callback للعناصر التي تسقط منه بحيث يبقى العدد الإجمالي عند 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() ، باستثناء استخدام قيمة العقدة بدلاً من قيمة المفتاح الفرعي المحدد.