קבלת הפניה למסד נתונים
כדי לקרוא נתונים ממסד הנתונים או לכתוב אליו, צריך מופע של DatabaseReference:
DatabaseReference ref = FirebaseDatabase.instance.ref();
רשימות קריאה וכתיבה
הוספה לרשימת נתונים
משתמשים ב-method push() כדי להוסיף נתונים לרשימה באפליקציות עם כמה משתמשים.
השיטה push() יוצרת מפתח ייחודי בכל פעם שנוסף צאצא חדש להפניה שצוינה ב-Firebase. כשמשתמשים במפתחות שנוצרים באופן אוטומטי לכל רכיב חדש ברשימה, כמה לקוחות יכולים להוסיף צאצאים לאותו מיקום בו-זמנית בלי התנגשויות כתיבה. המפתח הייחודי שנוצר על ידי push() מבוסס על חותמת זמן, כך שהפריטים ברשימה מסודרים באופן אוטומטי בסדר כרונולוגי.
אתם יכולים להשתמש בהפניה לנתונים החדשים שהוחזרו על ידי השיטה push() כדי לקבל את הערך של המפתח שנוצר באופן אוטומטי של הצאצא, או להגדיר נתונים לצאצא. המאפיין .key של הפניה מסוג push() מכיל את המפתח שנוצר אוטומטית.
אתם יכולים להשתמש במפתחות שנוצרו באופן אוטומטי כדי לפשט את מבנה הנתונים. מידע נוסף זמין בדוגמה להסתעפות נתונים.
לדוגמה, אפשר להשתמש ב-push() כדי להוסיף פוסט חדש לרשימת פוסטים באפליקציה קהילתית/חברתית:
DatabaseReference postListRef = FirebaseDatabase.instance.ref("posts");
DatabaseReference newPostRef = postListRef.push();
newPostRef.set({
// ...
});
האזנה לאירועים משניים
אירועים משניים מופעלים בתגובה לפעולות ספציפיות שמתרחשות בצאצאים של צומת, כמו הוספת צאצא חדש באמצעות השיטה push() או עדכון צאצא באמצעות השיטה update().
| אירוע | שימוש אופייני |
|---|---|
onChildAdded |
אחזור רשימות של פריטים או האזנה להוספות לרשימת פריטים. האירוע הזה מופעל פעם אחת לכל צאצא קיים, ואז שוב בכל פעם שנוסף צאצא חדש לנתיב שצוין. המאזין מקבל תמונת מצב שמכילה את הנתונים של הצאצא החדש. |
onChildChanged |
האזנה לשינויים בפריטים ברשימה. האירוע הזה מופעל בכל פעם שצומת צאצא משתנה. זה כולל כל שינוי בצאצאים של צומת הצאצא. תמונת המצב שמועברת לרכיב event listener מכילה את הנתונים המעודכנים של הצאצא. |
onChildRemoved |
האזנה לפריטים שמוסרים מרשימה. האירוע הזה מופעל כשמסירים צאצא מיידי.קובץ ה-snapshot שמועבר לבלוק ה-callback מכיל את הנתונים של הצאצא שהוסר. |
onChildMoved |
האזנה לשינויים בסדר הפריטים ברשימה ממוינת. אירועי onChildMoved תמיד מתרחשים אחרי אירוע onChildChanged שגרם לשינוי בסדר הפריטים (בהתאם לשיטת הסידור הנוכחית). |
השילוב של כל אלה יכול להיות שימושי להאזנה לשינויים בצומת ספציפי במסד נתונים. לדוגמה, אפליקציה של בלוג חברתי יכולה להשתמש בשיטות האלה ביחד כדי לעקוב אחרי הפעילות בתגובות של פוסט, כמו שמוצג בהמשך:
final commentsRef = FirebaseDatabase.instance.ref("post-comments/$postId");
commentsRef.onChildAdded.listen((event) {
// A new comment has been added, so add it to the displayed list.
});
commentsRef.onChildChanged.listen((event) {
// A comment has changed; use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
});
commentsRef.onChildRemoved.listen((event) {
// A comment has been removed; use the key to determine if we are displaying
// this comment and if so remove it.
});
האזנה לאירועי ערך
האזנה לאירועים משניים היא הדרך המומלצת לקרוא רשימות של נתונים, אבל יש מצבים שבהם כדאי להאזין לאירועי ערך בהפניה לרשימה.
אם מצרפים מאזין value לרשימת נתונים, כל רשימת הנתונים תוחזר כתמונת מצב אחת, ואז אפשר לעבור עליה בלולאה כדי לגשת לצאצאים ספציפיים.
גם אם יש רק התאמה אחת לשאילתה, תמונת המצב עדיין תהיה רשימה, אבל היא תכיל רק פריט אחד. כדי לגשת לפריט, צריך לעבור בלולאה על התוצאה:
myTopPostsQuery.onValue.listen((event) {
for (final child in event.snapshot.children) {
// Handle the post.
}
}, onError: (error) {
// Error.
});
התבנית הזו יכולה להיות שימושית כשרוצים לאחזר את כל הצאצאים של רשימה בפעולה אחת, במקום להאזין לאירועים נוספים של הוספת צאצאים.
מיון וסינון של נתונים
אפשר להשתמש במחלקה Query כדי לאחזר נתונים שממוינים לפי מפתח, לפי ערך או לפי ערך של צאצא. אפשר גם לסנן את התוצאה הממוינת למספר ספציפי של תוצאות או לטווח של מפתחות או ערכים.
מיון נתונים
כדי לאחזר נתונים ממוינים, קודם צריך לציין את אחת משיטות הסידור כדי לקבוע איך התוצאות יסודרו:
| שיטה | שימוש |
|---|---|
orderByChild() |
סידור התוצאות לפי הערך של מפתח צאצא מסוים או נתיב צאצא בתצוגת עץ. |
orderByKey() |
סידור התוצאות לפי מפתחות צאצא. |
orderByValue() |
סידור התוצאות לפי ערכי צאצא. |
אפשר להשתמש רק בשיטת סידור אחת בכל פעם. קריאה לשיטת הסידור כמה פעמים באותה שאילתה גורמת לשגיאה.
בדוגמה הבאה אפשר לראות איך מאחזרים רשימה של הפוסטים המובילים של משתמש, ממוינים לפי מספר הכוכבים שלהם:
final myUserId = FirebaseAuth.instance.currentUser?.uid;
final topUserPostsRef = FirebaseDatabase.instance
.ref("user-posts/$myUserId")
.orderByChild("starCount");
הקוד הזה מגדיר שאילתה שכאשר משלבים אותה עם מאזין צאצא, היא מסנכרנת את הלקוח עם הפוסטים של המשתמש מהנתיב במסד הנתונים על סמך מזהה המשתמש, לפי מספר הכוכבים שכל פוסט קיבל. השיטה הזו, של שימוש במזהים כמפתחות אינדקס, נקראת data fan out. תוכלו לקרוא עליה בהרחבה במאמר Structure Your Database.
הקריאה ל-method orderByChild() מציינת את מפתח הצאצא שלפיו יסודרו התוצאות. במקרה הזה, הפוסטים ממוינים לפי הערך של הצאצא "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, על ידי ציון הנתיב היחסי לצאצא המוטמע בקריאה ל-orderByChild().
final mostViewedPosts =
FirebaseDatabase.instance.ref('posts').orderByChild('metrics/views');
במאמר איך נתוני השאילתה מסודרים מוסבר איך סוגי נתונים אחרים מסודרים.
סינון נתונים
כדי לסנן נתונים, אפשר לשלב כל אחת משיטות ההגבלה או הטווח עם שיטת הסידור כשיוצרים שאילתה.
| שיטה | שימוש |
|---|---|
limitToFirst() |
מגדיר את המספר המקסימלי של פריטים שיוחזרו מתחילת רשימת התוצאות המסודרת. |
limitToLast() |
מגדירה את המספר המקסימלי של פריטים שיוחזרו מסוף הרשימה המסודרת של התוצאות. |
startAt() |
החזרת פריטים שגדולים מהמפתח או מהערך שצוין או שווים לו, בהתאם לשיטת הסידור שנבחרה. |
startAfter() |
החזרת פריטים שגדולים מהמפתח או מהערך שצוינו, בהתאם לשיטת הסידור שנבחרה. |
endAt() |
החזרת פריטים שקטנים מהמפתח או מהערך שצוינו או שווים להם, בהתאם לשיטת הסידור שנבחרה. |
endBefore() |
החזרת פריטים שהם קטנים מהמפתח או מהערך שצוינו, בהתאם לשיטת הסידור שנבחרה. |
equalTo() |
הפונקציה מחזירה פריטים ששווים למפתח או לערך שצוינו, בהתאם לשיטת הסידור שנבחרה. |
בניגוד לשיטות הסידור, אפשר לשלב כמה פונקציות של הגבלה או טווח.
לדוגמה, אפשר לשלב את השיטות startAt() ו-endAt() כדי להגביל את התוצאות לטווח ערכים מסוים.
הגבלת מספר התוצאות
אתם יכולים להשתמש בשיטות limitToFirst() ו-limitToLast() כדי להגדיר את המספר המקסימלי של אירועי צאצא שיסונכרנו לאירוע נתון. לדוגמה, אם משתמשים ב-limitToFirst() כדי להגדיר מגבלה של 100, בהתחלה מקבלים רק עד 100 אירועי onChildAdded. אם יש לכם פחות מ-100 פריטים שמאוחסנים במסד הנתונים של Firebase, אירוע onChildAdded מופעל לכל פריט.
כשהפריטים משתנים, אתם מקבלים אירועי onChildAdded לפריטים שנכנסים לשאילתה ואירועי onChildRemoved לפריטים שיוצאים ממנה, כך שהמספר הכולל נשאר 100.
בדוגמה הבאה מוצג איך אפליקציית בלוגים לדוגמה מגדירה שאילתה כדי לאחזר רשימה של 100 הפוסטים האחרונים של כל המשתמשים:
final recentPostsRef = FirebaseDatabase.instance.ref('posts').limitToLast(100);
בדוגמה הזו מוגדרת רק שאילתה. כדי לסנכרן את הנתונים בפועל, צריך לצרף לה מאזין.
סינון לפי מפתח או ערך
אפשר להשתמש ב-startAt(), startAfter(), endAt(), endBefore() ו-equalTo() כדי לבחור נקודות התחלה, סיום ושוויון שרירותיות לשאילתות. האפשרות הזו יכולה להיות שימושית כדי לחלק נתונים לדפים או למצוא פריטים עם צאצאים שיש להם ערך ספציפי.
איך נתוני השאילתות מסודרים
בקטע הזה מוסבר איך הנתונים ממוינים לפי כל אחת משיטות הסידור במחלקה Query.
orderByChild
כשמשתמשים ב-orderByChild(), הנתונים שמכילים את מפתח הצאצא שצוין מסודרים באופן הבא:
- ילדים עם ערך
nullלמפתח הצאצא שצוין מופיעים ראשונים. - אחריהם מופיעים צאצאים עם הערך
falseבמפתח הצאצא שצוין. אם לכמה צאצאים יש ערך שלfalse, הם ממוינים בסדר לקסיקוגרפי לפי מפתח. - אחריהם מופיעים צאצאים עם הערך
trueבמפתח הצאצא שצוין. אם לכמה צאצאים יש ערך שלtrue, הם ממוינים לפי סדר לקסיקוגרפי לפי מפתח. - אחריהם מופיעים צאצאים עם ערך מספרי, בסדר עולה. אם לכמה צאצאים יש ערך מספרי זהה בצומת הצאצא שצוין, הם ממוינים לפי מפתח.
- מחרוזות מופיעות אחרי מספרים וממוינות בסדר לקסיקוגרפי עולה. אם לכמה צאצאים יש אותו ערך בצומת הצאצא שצוין, הם מסודרים בסדר לקסיקוגרפי לפי מפתח.
- האובייקטים מופיעים בסוף וממוינים בסדר לקסיקוגרפי לפי מפתח בסדר עולה.
orderByKey
כשמשתמשים ב-orderByKey() כדי למיין את הנתונים, הנתונים מוחזרים בסדר עולה לפי מפתח.
- הילדים עם מפתח שאפשר לנתח כמספר שלם של 32 ביט מופיעים ראשונים, ממוינים בסדר עולה.
- אחריהם מופיעים צאצאים עם ערך מחרוזת כמפתח, ממוינים בסדר לקסיקוגרפי עולה.
orderByValue
כשמשתמשים ב-orderByValue(), הצאצאים מסודרים לפי הערך שלהם. הקריטריונים לסידור זהים לאלה של orderByChild(), אבל במקום הערך של מפתח צאצא שצוין, נעשה שימוש בערך של הצומת.
ניתוק מאזינים
כדי להסיר קריאות חוזרות, צריך להפעיל את השיטה off() בהפניה למסד הנתונים של Firebase.
כדי להסיר מאזין יחיד, אפשר להעביר אותו כפרמטר אל off().
הפעלת off() במיקום ללא ארגומנטים מסירה את כל המאזינים במיקום הזה.
קריאה ל-off() במאזין הורה לא מסירה באופן אוטומטי את המאזינים שרשומים בצומתי הצאצא שלו. צריך לקרוא ל-off() גם בכל מאזין צאצא כדי להסיר את הקריאה החוזרת (callback).