العمل مع قوائم البيانات على منصات Apple

احصل على FIRdatabaseReference

لقراءة البيانات أو كتابتها من قاعدة البيانات، تحتاج إلى مثيل FIRDatabaseReference :

سويفت

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
var ref: DatabaseReference!

ref = Database.database().reference()

ج موضوعية

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];

قوائم القراءة والكتابة

إلحاق بقائمة البيانات

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

يمكنك استخدام المرجع إلى البيانات الجديدة التي يتم إرجاعها بواسطة طريقة childByAutoId للحصول على قيمة المفتاح الذي تم إنشاؤه تلقائيًا للطفل أو تعيين البيانات للطفل. يؤدي استدعاء getKey على مرجع childByAutoId إلى إرجاع المفتاح الذي تم إنشاؤه تلقائيًا.

يمكنك استخدام هذه المفاتيح التي تم إنشاؤها تلقائيًا لتبسيط تسوية بنية البيانات الخاصة بك. لمزيد من المعلومات، راجع مثال توزيع البيانات.

الاستماع لأحداث الطفل

يتم تشغيل الأحداث الفرعية استجابة لعمليات محددة تحدث لأبناء العقدة من عملية مثل طفل جديد يضاف من خلال طريقة childByAutoId أو طفل يتم تحديثه من خلال طريقة updateChildValues .

نوع الحدث الاستخدام النموذجي
FIRDataEventTypeChildAdded استرداد قوائم العناصر أو الاستماع للإضافات إلى قائمة العناصر. يتم تشغيل هذا الحدث مرة واحدة لكل طفل موجود ثم مرة أخرى في كل مرة تتم إضافة طفل جديد إلى المسار المحدد. يتم تمرير للمستمع لقطة تحتوي على بيانات الطفل الجديد.
FIRDataEventTypeChildChanged استمع للتغييرات التي تطرأ على العناصر الموجودة في القائمة. يتم تشغيل هذا الحدث في أي وقت يتم فيه تعديل العقدة الفرعية. يتضمن هذا أي تعديلات على أحفاد العقدة الفرعية. تحتوي اللقطة التي تم تمريرها إلى مستمع الحدث على البيانات المحدثة للطفل.
FIRDataEventTypeChildRemoved استمع للعناصر التي تتم إزالتها من القائمة. يتم تشغيل هذا الحدث عند إزالة الطفل المباشر. تحتوي اللقطة التي تم تمريرها إلى كتلة رد الاتصال على بيانات الطفل الذي تمت إزالته.
FIRDataEventTypeChildMoved استمع للتغييرات في ترتيب العناصر في القائمة المرتبة. يتم تشغيل هذا الحدث عندما يتسبب التحديث في إعادة ترتيب الطفل. يتم استخدامه مع البيانات التي تم طلبها بواسطة queryOrderedByChild أو queryOrderedByValue .

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

سويفت

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
// Listen for new comments in the Firebase database
commentsRef.observe(.childAdded, with: { (snapshot) -> Void in
  self.comments.append(snapshot)
  self.tableView.insertRows(
    at: [IndexPath(row: self.comments.count - 1, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})
// Listen for deleted comments in the Firebase database
commentsRef.observe(.childRemoved, with: { (snapshot) -> Void in
  let index = self.indexOfMessage(snapshot)
  self.comments.remove(at: index)
  self.tableView.deleteRows(
    at: [IndexPath(row: index, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})

ج موضوعية

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
// Listen for new comments in the Firebase database
[_commentsRef
              observeEventType:FIRDataEventTypeChildAdded
              withBlock:^(FIRDataSnapshot *snapshot) {
                [self.comments addObject:snapshot];
                [self.tableView insertRowsAtIndexPaths:@[
                  [NSIndexPath indexPathForRow:self.comments.count - 1 inSection:kSectionComments]
                ]
                                      withRowAnimation:UITableViewRowAnimationAutomatic];
              }];
// Listen for deleted comments in the Firebase database
[_commentsRef
 observeEventType:FIRDataEventTypeChildRemoved
 withBlock:^(FIRDataSnapshot *snapshot) {
   int index = [self indexOfMessage:snapshot];
   [self.comments removeObjectAtIndex:index];
   [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:kSectionComments]]
                         withRowAnimation:UITableViewRowAnimationAutomatic];
 }];

استمع للأحداث القيمة

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

سيؤدي إرفاق مراقب FIRDataEventTypeValue بقائمة البيانات إلى إرجاع قائمة البيانات بأكملها كلقطة DataSnapshot واحدة، والتي يمكنك بعد ذلك تكرارها للوصول إلى العناصر الفرعية الفردية.

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

سويفت

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

ج موضوعية

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
[_commentsRef
              observeEventType:FIRDataEventTypeValue
              withBlock:^(FIRDataSnapshot *snapshot) {
                // Loop over children
                NSEnumerator *children = [snapshot children];
                FIRDataSnapshot *child;
                while (child = [children nextObject]) {
                  // ...
                }
              }];

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

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

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

فرز البيانات

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

طريقة الاستخدام
queryOrderedByKey ترتيب النتائج حسب المفاتيح الفرعية.
queryOrderedByValue ترتيب النتائج حسب القيم الفرعية.
queryOrderedByChild ترتيب النتائج حسب قيمة مفتاح فرعي محدد أو مسار فرعي متداخل.

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

يوضح المثال التالي كيف يمكنك استرداد قائمة بأهم منشورات المستخدم مرتبة حسب عدد النجوم:

سويفت

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
// My top posts by number of stars
let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")

ج موضوعية

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
// My top posts by number of stars
FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"]
                                      child:[super getUid]]
                                     queryOrderedByChild:@"starCount"];

يسترد هذا الاستعلام منشورات المستخدم من المسار في قاعدة البيانات بناءً على معرف المستخدم الخاص به، مرتبة حسب عدد النجوم التي تلقاها كل منشور. يُطلق على تقنية استخدام المعرفات كمفاتيح فهرس اسم "توزيع البيانات"، ويمكنك قراءة المزيد عنها في "هيكلة قاعدة البيانات الخاصة بك" .

يحدد استدعاء الأسلوب queryOrderedByChild المفتاح الفرعي لترتيب النتائج وفقًا له. في هذا المثال، يتم فرز المشاركات حسب قيمة النجم الفرعي "starCount" في كل مشاركة. يمكن أيضًا طلب الاستعلامات من خلال عناصر فرعية متداخلة، في حالة وجود بيانات تبدو كما يلي:

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

في هذه الحالة، يمكننا ترتيب عناصر قائمتنا حسب القيم المتداخلة تحت مفتاح metrics عن طريق تحديد المسار النسبي إلى الطفل المتداخل في استدعاء queryOrderedByChild الخاص بنا.

سويفت

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

ج موضوعية

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];

لمزيد من المعلومات حول كيفية ترتيب أنواع البيانات الأخرى، راجع كيفية ترتيب بيانات الاستعلام .

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

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

طريقة الاستخدام
queryLimitedToFirst يضبط الحد الأقصى لعدد العناصر المطلوب إرجاعها من بداية قائمة النتائج المرتبة.
queryLimitedToLast يضبط الحد الأقصى لعدد العناصر المراد إرجاعها من نهاية قائمة النتائج المرتبة.
queryStartingAtValue إرجاع عناصر أكبر من أو تساوي المفتاح أو القيمة المحددة، اعتمادًا على طريقة الترتيب التي تم اختيارها.
queryStartingAfterValue إرجاع عناصر أكبر من المفتاح أو القيمة المحددة، اعتمادًا على طريقة الترتيب التي تم اختيارها.
queryEndingAtValue قم بإرجاع عناصر أقل من أو تساوي المفتاح أو القيمة المحددة، اعتمادًا على طريقة الترتيب التي تم اختيارها.
queryEndingBeforeValue إرجاع عناصر أقل من المفتاح أو القيمة المحددة، اعتمادًا على طريقة الترتيب التي تم اختيارها.
queryEqualToValue قم بإرجاع عناصر مساوية للمفتاح أو القيمة المحددة، اعتمادًا على طريقة الترتيب التي تم اختيارها.

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

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

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

مع تغير العناصر، تتلقى ردود اتصال FIRDataEventTypeChildAdded للعناصر التي تدخل الاستعلام واستدعاءات FIRDataEventTypeChildRemoved للعناصر التي انسحبت منه بحيث يظل العدد الإجمالي عند 100.

يوضح المثال التالي كيف يمكن لأحد تطبيقات التدوين أن يسترد قائمة بأحدث 100 مشاركة بواسطة جميع المستخدمين:

سويفت

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!

ج موضوعية

ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];

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

يمكنك استخدام queryStartingAtValue و queryStartingAfterValue و queryEndingAtValue و queryEndingBeforeValue و queryEqualToValue لاختيار نقاط البداية والنهاية والتكافؤ العشوائية للاستعلامات. يمكن أن يكون هذا مفيدًا لتقسيم البيانات إلى صفحات أو البحث عن عناصر ذات عناصر فرعية لها قيمة محددة.

كيفية ترتيب بيانات الاستعلام

يشرح هذا القسم كيفية فرز البيانات حسب كل طريقة من طرق الترتيب في فئة FIRDatabaseQuery .

queryOrderedByKey

عند استخدام queryOrderedByKey لفرز بياناتك، يتم إرجاع البيانات بترتيب تصاعدي حسب المفتاح.

  1. الأطفال الذين لديهم مفتاح يمكن تحليله كعدد صحيح 32 بت يأتي أولاً، ويتم فرزهم بترتيب تصاعدي.
  2. يأتي بعد ذلك الأطفال الذين لديهم قيمة سلسلة كمفتاح، ويتم فرزهم بشكل معجمي بترتيب تصاعدي.

queryOrderedByValue

عند استخدام queryOrderedByValue ، يتم ترتيب الأطفال حسب قيمتهم. معايير الترتيب هي نفسها كما في queryOrderedByChild ، باستثناء قيمة العقدة المستخدمة بدلاً من قيمة المفتاح الفرعي المحدد.

queryOrderedByChild

عند استخدام queryOrderedByChild ، يتم ترتيب البيانات التي تحتوي على المفتاح الفرعي المحدد كما يلي:

  1. يأتي الأطفال الذين لديهم قيمة nil لمفتاح الطفل المحدد أولاً.
  2. يأتي بعد ذلك الأطفال الذين لديهم قيمة false لمفتاح الطفل المحدد. إذا كان لدى العديد من الأطفال قيمة false ، فسيتم فرزهم معجميًا حسب المفتاح.
  3. يأتي بعد ذلك الأطفال الذين لديهم قيمة true لمفتاح الطفل المحدد. إذا كان لدى العديد من الأطفال قيمة true ، فسيتم فرزهم معجميًا حسب المفتاح.
  4. يأتي بعد ذلك الأطفال ذوو القيمة الرقمية، ويتم فرزهم بترتيب تصاعدي. إذا كان لدى العديد من الأطفال نفس القيمة الرقمية للعقدة الفرعية المحددة، فسيتم فرزهم حسب المفتاح.
  5. تأتي السلاسل بعد الأرقام ويتم فرزها معجميًا بترتيب تصاعدي. إذا كان لدى العديد من الأطفال نفس القيمة للعقدة الفرعية المحددة، فسيتم ترتيبهم معجميًا حسب المفتاح.
  6. تأتي الكائنات أخيرًا ويتم فرزها معجميًا حسب المفتاح بترتيب تصاعدي.

افصل المستمعين

لا يتوقف المراقبون عن مزامنة البيانات تلقائيًا عند مغادرة ViewController . إذا لم تتم إزالة المراقب بشكل صحيح، فسيستمر في مزامنة البيانات مع الذاكرة المحلية وسيحتفظ بأي كائنات تم التقاطها في إغلاق معالج الحدث، مما قد يتسبب في تسرب الذاكرة. عندما لا تكون هناك حاجة إلى مراقب، قم بإزالته عن طريق تمرير FIRDatabaseHandle المرتبط إلى الأسلوب removeObserverWithHandle .

عند إضافة كتلة رد اتصال إلى مرجع، يتم إرجاع FIRDatabaseHandle . يمكن استخدام هذه المقابض لإزالة كتلة رد الاتصال.

إذا تمت إضافة عدة مستمعين إلى مرجع قاعدة بيانات، فسيتم استدعاء كل مستمع عند رفع حدث ما. لإيقاف مزامنة البيانات في ذلك الموقع، يجب عليك إزالة جميع المراقبين في الموقع عن طريق استدعاء الأسلوب removeAllObservers .

لا يؤدي استدعاء removeObserverWithHandle أو removeAllObservers على المستمع إلى إزالة المستمعين المسجلين في العقد الفرعية الخاصة به تلقائيًا؛ يجب عليك أيضًا تتبع تلك المراجع أو المقابض لإزالتها.

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