במסמך הזה נסביר את העקרונות הבסיסיים של אחזור נתונים ואת הדרכים למיון ולסינון של נתוני Firebase.
לפני שמתחילים
חשוב לוודא שהגדרתם את האפליקציה ושיש לכם גישה למסד הנתונים, כפי שמתואר במדריך Get Started
.
אחזור נתונים
אפשר לאחזר נתונים מ-Firebase באמצעות קריאה חד-פעמית ל-GetValue()
או באמצעות צירוף ל-ValueListener
בהפניה של FirebaseDatabase
. הקריאה למאזין הערכים מתבצעת פעם אחת לגבי המצב הראשוני של הנתונים, ופעם נוספת בכל פעם שהנתונים משתנים.
אחזור של DatabaseReference
כדי לכתוב נתונים במסד הנתונים, צריך מופע של DatabaseReference
:
// Get the root reference location of the database. firebase::database::DatabaseReference dbref = database->GetReference();
קריאת נתונים פעם אחת
אפשר להשתמש בשיטה GetValue()
כדי לקרוא תמונת מצב סטטית של התוכן בנתיב נתון פעם אחת. תוצאת המשימה תכלול קובץ snapshot שמכיל את כל הנתונים במיקום הזה, כולל נתוני הצאצאים. אם אין נתונים, קובץ ה-snapshot המוחזר הוא null
.
firebase::Future<firebase::database::DataSnapshot> result = dbRef.GetReference("Leaders").GetValue();
בשלב שבו הבקשה נשלחת, אנחנו צריכים להמתין עד שהפעולה ב-Future תושלם כדי שנוכל לקרוא את הערך. משחקים פועלים בדרך כלל בלולאה, והם פחות מונחים על קריאות חזרה (callbacks) מאשר אפליקציות אחרות, לכן בדרך כלל מבצעים סקרים כדי לבדוק אם הם הושלמו.
// In the game loop that polls for the result... if (result.status() != firebase::kFutureStatusPending) { if (result.status() != firebase::kFutureStatusComplete) { LogMessage("ERROR: GetValue() returned an invalid result."); // Handle the error... } else if (result.error() != firebase::database::kErrorNone) { LogMessage("ERROR: GetValue() returned error %d: %s", result.error(), result.error_message()); // Handle the error... } else { firebase::database::DataSnapshot snapshot = result.result(); // Do something with the snapshot... } }
כאן מוצגת בדיקת שגיאות בסיסית. למידע נוסף על בדיקת שגיאות ועל דרכים לקבוע מתי התוצאה מוכנה, אפשר לעיין במסמך העזרה של firebase::Future.
האזנה לאירועים
אפשר להוסיף מאזינים כדי להירשם לשינויים בנתונים:
ValueListener
מחלקה בסיסית
התקשרות חזרה | שימוש רגיל |
---|---|
OnValueChanged |
קריאה והאזנה לשינויים בכל התוכן של נתיב. |
OnChildListener
מחלקה בסיסית
OnChildAdded
| אחזור רשימות של פריטים או האזנה להוספות לרשימת פריטים.
מומלץ להשתמש ב-OnChildChanged וב-OnChildRemoved כדי לעקוב אחרי שינויים ברשימות. |
OnChildChanged |
האזנה לשינויים בפריטים ברשימה. אפשר להשתמש ב-OnChildAdded וב-OnChildRemoved כדי לעקוב אחרי שינויים ברשימות. |
OnChildRemoved |
האזנה לפריטים שמוסרים מרשימת פריטים. אפשר להשתמש ב-OnChildAdded וב-OnChildChanged כדי לעקוב אחרי שינויים ברשימות. |
OnChildMoved |
האזנה לשינויים בסדר הפריטים ברשימה מסודרת.
קריאות החזרה (callbacks) של OnChildMoved תמיד מגיעות אחרי קריאות החזרה של OnChildChanged , כי סדר הפריטים משתנה (על סמך שיטת הסדר הנוכחית). |
הכיתה ValueListener
אפשר להשתמש בקריאות החזרה (callbacks) של OnValueChanged
כדי להירשם לשינויים בתוכן בנתיב נתון. הקריאה החוזרת הזו מופעלת פעם אחת כשהמאזין מצורף, ופעם נוספת בכל פעם שהנתונים, כולל הצאצאים, משתנים. בקריאה החוזרת מועברת קובץ snapshot שמכיל את כל הנתונים במיקום הזה, כולל נתוני הצאצאים. אם אין נתונים, קובץ ה-snapshot המוחזר הוא null
.
הדוגמה הבאה ממחישה משחק שמאחזר את הציונים של לוח מנהיגים ממסד הנתונים:
class LeadersValueListener : public firebase::database::ValueListener { public: void OnValueChanged( const firebase::database::DataSnapshot& snapshot) override { // Do something with the data in snapshot... } void OnCancelled(const firebase::database::Error& error_code, const char* error_message) override { LogMessage("ERROR: LeadersValueListener canceled: %d: %s", error_code, error_message); } }; // Elsewhere in the code... LeadersValueListener* listener = new LeadersValueListener(); firebase::Future<firebase::database::DataSnapshot> result = dbRef.GetReference("Leaders").AddValueListener(listener);
התוצאה של Future<DataSnapshot>
מכילה את הנתונים במיקום שצוין במסד הנתונים בזמן האירוע. קריאה ל-value()
בתמונת מצב מחזירה Variant
שמייצג את הנתונים.
בדוגמה הזו, גם השיטה OnCancelled
מוחרגת כדי לבדוק אם הקריאה בוטלה. לדוגמה, קריאה יכולה להתבטל אם ללקוח אין הרשאה לקרוא ממיקום של מסד נתונים ב-Firebase. השדה database::Error
יציין את הסיבה לכישלון.
הכיתה ChildListener
אירועי הצאצאים מופעלים בתגובה לפעולות ספציפיות שקורות לצאצאים של צומת מפעולה, כמו צאצא חדש שנוסף באמצעות השיטה PushChild()
או צאצא שמתעדכן באמצעות השיטה UpdateChildren()
. כל אחד מהם יכול להיות שימושי לצורך האזנה לשינויים בצומת ספציפי במסד נתונים. לדוגמה, יכול להיות ששיטה אחת תשמש יחד עם השנייה במשחק כדי לעקוב אחרי הפעילות בתגובות לסשן של המשחק, כפי שמתואר בהמשך:
class SessionCommentsChildListener : public firebase::database::ChildListener { public: void OnChildAdded(const firebase::database::DataSnapshot& snapshot, const char* previous_sibling) override { // Do something with the data in snapshot ... } void OnChildChanged(const firebase::database::DataSnapshot& snapshot, const char* previous_sibling) override { // Do something with the data in snapshot ... } void OnChildRemoved( const firebase::database::DataSnapshot& snapshot) override { // Do something with the data in snapshot ... } void OnChildMoved(const firebase::database::DataSnapshot& snapshot, const char* previous_sibling) override { // Do something with the data in snapshot ... } void OnCancelled(const firebase::database::Error& error_code, const char* error_message) override { LogMessage("ERROR: SessionCommentsChildListener canceled: %d: %s", error_code, error_message); } }; // elsewhere .... SessionCommentsChildListener* listener = new SessionCommentsChildListener(); firebase::Future<firebase::database::DataSnapshot> result = dbRef.GetReference("GameSessionComments").AddChildListener(listener);
בדרך כלל משתמשים ב-callback של OnChildAdded
כדי לאחזר רשימה של פריטים במסד נתונים של Firebase. פונקציית ה-callback OnChildAdded
נקראת פעם אחת לכל צאצא קיים, ואז שוב בכל פעם שנוסף צאצא חדש לנתיב שצוין. למאזין מועברת קובץ snapshot שמכיל את הנתונים של הצאצא החדש.
פונקציית ה-callback OnChildChanged
נקראת בכל פעם שצוין שינוי בצומת צאצא.
זה כולל שינויים בכל הצאצאים של צומת הצאצא. בדרך כלל משתמשים בה בשילוב עם הקריאות OnChildAdded
ו-OnChildRemoved
כדי להגיב לשינויים ברשימת פריטים. קובץ snapshot שמוענק למאזין מכיל את הנתונים המעודכנים של הצאצא.
קריאת החזרה (callback) של OnChildRemoved
מופעלת כשמוסרים צאצא מיידי.
בדרך כלל משתמשים בו בשילוב עם הפונקציות החוזרות OnChildAdded
ו-OnChildChanged
. קובץ snapshot שמוענק ל-callback מכיל את הנתונים של הילד או הילדה שהוסרו.
קריאת החזרה (callback) של OnChildMoved
מופעלת בכל פעם שהקריאה של OnChildChanged
מתעוררת כתוצאה מעדכון שגורם לסדר מחדש של הצאצא. הוא משמש עם נתונים שממוינים באמצעות OrderByChild
או OrderByValue
.
מיון וסינון של נתונים
אפשר להשתמש בכיתה Realtime Database Query
כדי לאחזר נתונים שממוינים לפי מפתח, לפי ערך או לפי ערך של צאצא. אפשר גם לסנן את התוצאה הממוינת למספר ספציפי של תוצאות או לטווח של מפתחות או ערכים.
מיון נתונים
כדי לאחזר נתונים ממוינים, קודם צריך לציין אחת משיטות הסדר כדי לקבוע את סדר התוצאות:
שיטה | שימוש |
---|---|
OrderByChild() |
מיון התוצאות לפי הערך של מפתח צאצא ספציפי. |
OrderByKey()
| מיון התוצאות לפי מפתחות צאצאים. |
OrderByValue() |
מיון התוצאות לפי ערכי הצאצאים. |
אפשר להשתמש רק בשיטה אחת לסדר את הרשימה בכל פעם. קריאה ל-method מסוג order-by מספר פעמים באותה שאילתה תגרום לשגיאה.
הדוגמה הבאה מראה איך אפשר להירשם למצעד מנהיגים של ציונים שממוינים לפי ציון.
firebase::database::Query query = dbRef.GetReference("Leaders").OrderByChild("score"); // To get the resulting DataSnapshot either use query.GetValue() and poll the // future, or use query.AddValueListener() and register to handle the // OnValueChanged callback.
כך מגדירים את firebase::Query
, שכשמשלבים אותו עם ValueListener הוא מסנכרן את הלקוח עם לוח הבקרה במסד הנתונים, לפי הסדר של הציון של כל רשומה.
מידע נוסף על בניית מבנה יעיל לנתונים זמין במאמר בניית מבנה למסד הנתונים.
בקריאה ל-method OrderByChild()
מציינים את מפתח הצאצא לפיו רוצים למיין את התוצאות. במקרה כזה, התוצאות ממוינות לפי הערך של הערך "score"
בכל הצאצאים. מידע נוסף על סדר של סוגים אחרים של נתונים זמין במאמר איך מתבצע הסדר של נתוני השאילתות.
סינון נתונים
כדי לסנן נתונים, אפשר לשלב כל אחת מהשיטות של limit או range עם שיטת order-by כשיוצרים שאילתה.
שיטה | שימוש |
---|---|
LimitToFirst() |
מגדיר את המספר המקסימלי של פריטים להחזרה מתחילת רשימת התוצאות הממוזערת. |
LimitToLast() |
מגדיר את המספר המקסימלי של פריטים להחזרה מסוף רשימת התוצאות הממוזערת. |
StartAt() |
החזרת פריטים שגדולים או שווים למפתח או לערך שצוינו, בהתאם לשיטת הסדר שנבחרה. |
EndAt() |
הפונקציה מחזירה פריטים שקטנים או שווים למפתח או לערך שצוינו, בהתאם לשיטת הסדר שנבחרה. |
EqualTo() |
הפונקציה מחזירה פריטים שווים למפתח או לערך שצוינו, בהתאם לשיטת הסדר שנבחרה. |
בניגוד לשיטות order-by, אפשר לשלב כמה פונקציות של הגבלה או טווח.
לדוגמה, אפשר לשלב את השיטות StartAt()
ו-EndAt()
כדי להגביל את התוצאות לטווח ערכים מסוים.
גם אם יש רק התאמה אחת לשאילתה, קובץ snapshot עדיין הוא רשימה, אלא שהוא מכיל רק פריט אחד.
הגבלת מספר התוצאות
אפשר להשתמש בשיטות LimitToFirst()
ו-LimitToLast()
כדי להגדיר את מספר הצאצאים המקסימלי שיסונכרנו בקריאה חוזרת נתונה. לדוגמה, אם משתמשים ב-LimitToFirst()
כדי להגדיר מגבלה של 100, בהתחלה מקבלים רק עד 100 קריאות חזרה של OnChildAdded
. אם יש לכם פחות מ-100 פריטים שמאוחסנים במסד הנתונים של Firebase, תיגרם קריאה חוזרת (callback) של OnChildAdded
לכל פריט.
כשהפריטים משתנים, אתם מקבלים OnChildAdded
קריאות חזרה (callbacks) על פריטים שמתווספים לשאילתה ו-OnChildRemoved
קריאות חזרה על פריטים שיוצאים ממנה, כך שהמספר הכולל נשאר 100.
לדוגמה, הקוד הבא מחזיר את הציון הגבוה ביותר מראש טבלת הדירוג:
firebase::database::Query query = dbRef.GetReference("Leaders").OrderByChild("score").LimitToLast(1); // To get the resulting DataSnapshot either use query.GetValue() and poll the // future, or use query.AddValueListener() and register to handle the // OnValueChanged callback.
סינון לפי מפתח או ערך
אפשר להשתמש ב-StartAt()
, ב-EndAt()
וב-EqualTo()
כדי לבחור נקודות התחלה, סיום ודומות שרירותיות לשאילתות. האפשרות הזו יכולה להיות שימושית כדי לפלח את הנתונים או למצוא פריטים עם צאצאים שיש להם ערך ספציפי.
איך מתבצע הסדר של נתוני השאילתה
בקטע הזה מוסבר איך הנתונים ממוינים לפי כל אחת משיטות הסדר בכיתה Query
.
OrderByChild
כשמשתמשים ב-OrderByChild()
, הנתונים שמכילים את מפתח הצאצא שצוין ממוינים באופן הבא:
- צאצאים עם ערך
null
למפתח הצאצא שצוין מופיעים קודם. - לאחר מכן מופיעים צאצאים עם הערך
false
למפתח הצאצא שצוין. אם יש כמה צאצאים עם הערךfalse
, הם ממוינים לפי אלפבית לפי מפתח. - לאחר מכן מופיעים צאצאים עם הערך
true
למפתח הצאצא שצוין. אם ליותר מילד אחד יש ערך שלtrue
, הם ממוינים לפי מפתח לפי סדר אלפביתי. - לאחר מכן מופיעים צאצאים עם ערך מספרי, שממוינים בסדר עולה. אם ליותר מילד אחד יש את אותו ערך מספרי בצומת הצאצא שצוין, הם ממוינים לפי מפתח.
- מחרוזות מופיעות אחרי מספרים וממוינות לפי סדר אלפביתי עולה. אם לכמה צאצאים יש אותו ערך בצומת הצאצא שצוין, הם ממוינים לפי מפתח אלפביתי.
- האובייקטים מופיעים בסוף וממוינים לפי מפתח מילוני בסדר עולה.
OrderByKey
כשמשתמשים ב-OrderByKey()
כדי למיין את הנתונים, הנתונים מוחזרים בסדר עולה לפי מפתח.
- צאצאים עם מפתח שאפשר לנתח כמספר שלם של 32 ביט מופיעים קודם, וממוינים בסדר עולה.
- לאחר מכן מופיעים צאצאים עם ערך מחרוזת כמפתח, שממוינים לפי סדר אלפביתי עולה.
OrderByValue
כשמשתמשים ב-OrderByValue()
, הצאצאים ממוינים לפי הערך שלהם. קריטריונים הסדר זהים לקריטריונים של OrderByChild()
, אלא שהערך של הצומת משמש במקום הערך של מפתח צאצא שצוין.