الحصول على 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
بقائمة بيانات إلى عرض القائمة الكاملة للبيانات على أنها DataSnapshot واحدة، والتي يمكنك تكرارها للوصول إلى العناصر الثانوية الفردية.
حتى عندما يكون هناك تطابق واحد فقط لطلب البحث، تظل اللقطة قائمة؛ بل تحتوي فقط على عنصر واحد. للوصول إلى العنصر، تحتاج إلى التكرار حول النتيجة:
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]) { // ... } }];
ويمكن أن يكون هذا النمط مفيدًا عندما تريد جلب جميع العناصر الثانوية للقائمة في عملية واحدة، بدلاً من الاستماع إلى الأحداث الإضافية الثانوية المضافة.
فرز البيانات وتصفيتها
يمكنك استخدام الفئة 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"];
يسترد هذا الاستعلام مشاركات المستخدم من المسار في قاعدة البيانات استنادًا إلى رقم تعريف المستخدم، ويتم ترتيبها حسب عدد النجوم التي حصلت عليها كل مشاركة. يُطلق على أسلوب استخدام أرقام التعريف كمفاتيح فهرس اسم "توزيع البيانات"، ويمكنك قراءة المزيد عنها في تنظيم قاعدة البيانات.
يحدد استدعاء الإجراء 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
.
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
على أحد المستمعين إلى
إزالة المستمعين المسجَّلين في العُقد الفرعية تلقائيًا، بل عليكم أيضًا تتبُّع هذه الإشارات أو الأسماء المعرِّفة لإزالتها.