קבלת קובץ FIRDatabaseReference
כדי לקרוא או לכתוב נתונים מהמסד הנתונים, צריך מופע של FIRDatabaseReference
:
Swift
var ref: DatabaseReference! ref = Database.database().reference()
Objective-C
@property (strong, nonatomic) FIRDatabaseReference *ref; self.ref = [[FIRDatabase database] reference];
קריאה וכתיבה של רשימות
הוספה לרשימה של נתונים
משתמשים בשיטה childByAutoId
כדי לצרף נתונים לרשימה באפליקציות עם כמה משתמשים. ה-method childByAutoId
יוצרת מפתח ייחודי בכל פעם שמתווסף צאצא חדש לקובץ העזר הספציפי של Firebase. השימוש במפתחות האלה שנוצרים באופן אוטומטי לכל רכיב חדש ברשימה מאפשר למספר לקוחות להוסיף צאצאים לאותו מיקום בו-זמנית, בלי התנגשויות בכתיבה. המפתח הייחודי שנוצר על ידי childByAutoId
מבוסס על חותמת זמן, כך שפריטי הרשימה ממוינים באופן כרונולוגי באופן אוטומטי.
אפשר להשתמש בהפניה לנתונים החדשים שמוחזרים על ידי השיטה childByAutoId
כדי לקבל את הערך של המפתח שנוצר באופן אוטומטי של הצאצא, או כדי להגדיר נתונים עבור הצאצא.
קריאה אל getKey
בהפניה של childByAutoId
תחזיר את המפתח שנוצר באופן אוטומטי.
אפשר להשתמש במפתחות שנוצרו באופן אוטומטי כדי לפשט את מבנה הנתונים. מידע נוסף זמין בדוגמה של פיזור נתונים.
האזנה לאירועים של ילדים
אירועי צאצא מופעלים בתגובה לפעולות ספציפיות שמתרחשות צאצאים של צומת מפעולה, כמו צאצא חדש שנוסף באמצעות method childByAutoId
או צאצא שמתעדכן באמצעות השיטה updateChildValues
.
סוג האירוע | שימוש רגיל |
---|---|
FIRDataEventTypeChildAdded |
אחזור רשימות של פריטים או האזנה להוספות לרשימת פריטים. האירוע הזה מופעל פעם אחת לכל צאצא קיים, ואז שוב בכל פעם שמתווסף צאצא חדש לנתיב שצוין. למאזין מועברת קובץ snapshot שמכיל את הנתונים של הצאצא החדש. |
FIRDataEventTypeChildChanged |
מאזינים לשינויים בפריטים שברשימה. האירוע הזה מופעל בכל פעם שצומת צאצא משתנה. זה כולל שינויים צאצאים של הצומת הצאצא. תמונת המצב שמועברת למאזין האירועים מכילה את הנתונים המעודכנים של הצאצא. |
FIRDataEventTypeChildRemoved |
האזנה לפריטים שמוסרים מרשימת פריטים. האירוע הזה מופעל כאשר צאצא ישיר מסוים מוסר. קובץ ה-snapshot שמוענק לבלוק של פונקציית ה-callback מכיל את הנתונים של הצאצא שהוסרו. |
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 יחיד, שאפשר יהיה להריץ בו לולאה כדי לגשת לצאצאים ספציפיים.
גם אם יש רק התאמה אחת לשאילתה, קובץ snapshot עדיין יהיה רשימה, רק שהוא יכיל פריט אחד. כדי לגשת לפריט, צריך להריץ לולאה על התוצאה:
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 |
מיון התוצאות לפי הערך של מפתח צאצא או נתיב צאצא בתצוגת עץ שצוין. |
אפשר להשתמש רק בשיטה אחת לסדר את הרשימה בכל פעם. קריאה ל-method מסוג order-by מספר פעמים באותה שאילתה תגרום לשגיאה.
בדוגמה הבאה מוסבר איך אפשר לאחזר רשימה של הפוסטים המובילים של משתמש, ממוינים לפי מספר הכוכבים:
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"];
השאילתה הזו מאחזרת את הפוסטים של המשתמש מהנתיב במסד הנתונים על סמך מזהה המשתמש שלו, ומסודרת לפי מספר הכוכבים שקיבל כל פוסט. השיטה הזו של שימוש במזהים כמפתחות אינדקס נקראת 'דחיית נתונים'. מידע נוסף זמין במאמר מבנה מסד הנתונים.
הקריאה ל-method 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"];
למידע נוסף על הסדר של סוגי נתונים אחרים, ראו אופן הסדר של נתוני שאילתות.
סינון נתונים
כדי לסנן נתונים, אפשר לשלב כל אחת מהשיטות של limit או range עם שיטת order-by כשיוצרים שאילתה.
שיטה | שימוש |
---|---|
queryLimitedToFirst |
מגדיר את המספר המקסימלי של פריטים להחזרה מתחילת רשימת התוצאות הממוזערת. |
queryLimitedToLast |
מגדיר את המספר המקסימלי של פריטים להחזרה מסוף רשימת התוצאות הממוזערת. |
queryStartingAtValue |
החזרת פריטים שגדולים מהמפתח או מהערך שצוינו או שווים להם, בהתאם לשיטת הסדר שנבחרה. |
queryStartingAfterValue |
הפונקציה מחזירה פריטים שגדולים מהמפתח או מהערך שצוינו, בהתאם לשיטת הסדר שבחרתם. |
queryEndingAtValue |
הפונקציה מחזירה פריטים שערכם קטן או שווה למפתח או לערך שצוינו, בהתאם לשיטת הסדר שנבחרה. |
queryEndingBeforeValue |
הפונקציה מחזירה פריטים שערכם קטן מהמפתח או מהערך שצוינו, בהתאם לשיטת הסדר שנבחרה. |
queryEqualToValue |
הפונקציה מחזירה פריטים שווים למפתח או לערך שצוינו, בהתאם לשיטת הסדר שנבחרה. |
בניגוד לשיטות order-by, אפשר לשלב כמה פונקציות של מגבלות או טווחים.
לדוגמה, אפשר לשלב את השיטות queryStartingAtValue
ו-queryEndingAtValue
כדי להגביל את התוצאות לטווח ערכים מסוים.
הגבלת מספר התוצאות
אפשר להשתמש ב-methods queryLimitedToFirst
ו-queryLimitedToLast
כדי להגדיר מספר מקסימלי של צאצאים שיסונכרנו בקריאה חוזרת (callback) נתונה. לדוגמה, אם משתמשים ב-queryLimitedToFirst
כדי להגדיר מגבלה של 100, בהתחלה מקבלים רק עד 100 קריאות חזרה של FIRDataEventTypeChildAdded
. אם יש פחות מ-100 פריטים במסד הנתונים של Firebase, תתבצע קריאה חוזרת של FIRDataEventTypeChildAdded
לכל פריט.
כשפריטים משתנים, מקבלים FIRDataEventTypeChildAdded
קריאות חוזרות (callbacks) לפריטים מזינים את השאילתה ו-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
. אם לא מסירים את הצופה בצורה נכונה, הוא ממשיך לסנכרן נתונים עם הזיכרון המקומי ולשמור את כל האובייקטים שצולמו ב-closure של טיפול האירוע, דבר שעלול לגרום לדליפות זיכרון. כשכבר אין צורך בצופה, מעבירים את ה-FIRDatabaseHandle
המשויך ל-method removeObserverWithHandle
כדי להסיר אותו.
כשמוסיפים בלוק של קריאה חוזרת להפניה, מוחזר FIRDatabaseHandle
.
אפשר להשתמש במזהים האלה כדי להסיר את הבלוק של קריאת החזרה (callback).
אם נוספו מספר מאזינים לקובץ עזר של מסד נתונים, מתבצעת קריאה לכל האזנה כשמועלה אירוע. כדי להפסיק את סנכרון הנתונים במיקום הזה, צריך להסיר את כל המשתמשים שמנטרלים את המיקום באמצעות קריאה ל-method removeAllObservers
.
קריאה ל-removeObserverWithHandle
או ל-removeAllObservers
על מאזין לא מסירה באופן אוטומטי מאזינים שרשומים בצמתים הצאצאים שלו. כדי להסיר אותם, צריך גם לעקוב אחרי ההפניות או כינויי המזהה האלה.