الحصول على FIRDatabaseReference
لقراءة البيانات من قاعدة البيانات أو كتابتها، تحتاج إلى مثيل من
FIRDatabaseReference:
Swift
var ref: DatabaseReference! ref = Database.database().reference()
Objective-C
@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.
|
يمكن أن يكون كلّ من هذه العناصر مفيدًا للاستماع إلى التغييرات في عقدة معيّنة في قاعدة البيانات. على سبيل المثال، قد يستخدم تطبيق تدوين اجتماعي هذه الطرق معًا لمراقبة النشاط في تعليقات منشور، كما هو موضح أدناه:
Swift
// 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 ) })
Objective-C
// 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 بقائمة بيانات إلى عرض قائمة البيانات بالكامل كلقطة بيانات واحدة، والتي يمكنك بعد ذلك تكرارها للوصول إلى العناصر الفرعية الفردية.
حتى عندما يكون هناك تطابق واحد فقط لطلب البحث، تظل اللقطة قائمة، ولكنها تحتوي على عنصر واحد فقط. للوصول إلى العنصر، تحتاج إلى تكرار النتيجة:
Swift
_commentsRef.observe(.value) { snapshot in for child in snapshot.children { ... } }
Objective-C
[_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 |
يمكنك ترتيب النتائج حسب قيمة مفتاح فرعي محدّد أو مسار فرعي مدمج. |
يمكنك استخدام طريقة ترتيب واحدة فقط في كل مرة. يؤدي استدعاء طريقة الترتيب عدة مرات في طلب البحث نفسه إلى ظهور خطأ.
يوضّح المثال التالي كيفية استرداد قائمة بأهم منشورات المستخدم مرتّبة حسب عدد النجوم:
Swift
// My top posts by number of stars let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")
Objective-C
// My top posts by number of stars FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"] child:[super getUid]] queryOrderedByChild:@"starCount"];
يسترد هذا الطلب مشاركات المستخدم من المسار في قاعدة البيانات استنادًا إلى رقم تعريف المستخدم، ويتم ترتيبها حسب عدد النجوم التي حصلت عليها كل مشاركة. تُعرف هذه التقنية لاستخدام المعرّفات كمفاتيح فهرسة باسم "توزيع البيانات"، ويمكنك الاطّلاع على مزيد من المعلومات عنها في مقالة بناء قاعدة بياناتك.
The call to the queryOrderedByChild method specifies the child key to order
the results by. في هذا المثال، يتم ترتيب المشاركات حسب قيمة
الفرع "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.
Swift
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")
Objective-C
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 منشور لجميع المستخدمين:
Swift
// Last 100 posts, these are automatically the 100 most recent // due to sorting by push() keys let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!
Objective-C
// 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 لترتيب بياناتك، يتم عرض البيانات بترتيب تصاعدي
حسب المفتاح.
- تظهر أولاً العناصر الفرعية التي تحتوي على مفتاح يمكن تحليله كعدد صحيح مكوّن من 32 بت، ويتم ترتيبها تصاعديًا.
- بعد ذلك، يتم ترتيب العناصر الثانوية التي تحتوي على قيمة سلسلة كمفتاح لها، ويتم ترتيبها معجميًا تصاعديًا.
queryOrderedByValue
عند استخدام queryOrderedByValue، يتم ترتيب العناصر الفرعية حسب قيمتها. معايير الترتيب هي نفسها في queryOrderedByChild، باستثناء أنّه يتم استخدام قيمة العقدة بدلاً من قيمة مفتاح فرعي محدّد.
queryOrderedByChild
عند استخدام queryOrderedByChild، يتم ترتيب البيانات التي تحتوي على المفتاح الفرعي المحدد على النحو التالي:
- تظهر أولاً العناصر الفرعية التي لها قيمة
nilلمفتاح الطفل المحدّد. - تأتي بعد ذلك العناصر الثانوية التي لها القيمة
falseللمفتاح الثانوي المحدّد. إذا كان لدى عدة عناصر فرعية قيمةfalse، يتم ترتيبها معجميًا حسب المفتاح. - تأتي بعد ذلك العناصر الثانوية التي لها القيمة
trueللمفتاح الثانوي المحدّد. إذا كان لدى عدة عناصر فرعية قيمةtrue، يتم ترتيبها معجميًا حسب المفتاح. - تأتي بعد ذلك العناصر الثانوية التي لها قيمة رقمية، ويتم ترتيبها تصاعديًا. إذا كان هناك عدة عناصر فرعية لها القيمة الرقمية نفسها للعقدة الفرعية المحددة، يتم ترتيبها حسب المفتاح.
- تأتي السلاسل بعد الأرقام ويتم ترتيبها معجميًا بترتيب تصاعدي. إذا كان لدى عدة عناصر فرعية القيمة نفسها للعقدة الفرعية المحددة، يتم ترتيبها معجميًا حسب المفتاح.
- تأتي العناصر في النهاية ويتم ترتيبها معجميًا حسب المفتاح بترتيب تصاعدي.
فصل المستمعين
لا يتوقف المراقبون تلقائيًا عن مزامنة البيانات عند مغادرة
ViewController. إذا لم تتم إزالة المراقب بشكل صحيح، سيستمر في مزامنة البيانات مع الذاكرة المحلية وسيحتفظ بأي عناصر تم التقاطها في إغلاق معالج الأحداث، مما قد يتسبب في تسرّب الذاكرة. عندما لا تكون هناك حاجة إلى المراقب،
يمكنك إزالته من خلال تمرير FIRDatabaseHandle المرتبط به إلى
طريقة removeObserverWithHandle.
عند إضافة مجموعة ردّ اتصال إلى مرجع، يتم عرض FIRDatabaseHandle.
يمكن استخدام هذه المقابض لإزالة مجموعة عمليات الاستدعاء.
في حال إضافة عدة أدوات معالجة إلى مرجع قاعدة بيانات، يتم استدعاء كل أداة معالجة عند ظهور حدث. لإيقاف مزامنة البيانات في ذلك الموقع الجغرافي،
عليك إزالة جميع المراقبين في الموقع الجغرافي من خلال استدعاء الطريقة removeAllObservers.
لا يؤدي استدعاء removeObserverWithHandle أو removeAllObservers على مستمع إلى إزالة المستمعين المسجلين على العُقد الفرعية تلقائيًا، بل يجب أيضًا تتبُّع هذه المراجع أو المعالجات لإزالتها.