במאמר הזה נסביר איך מאחזרים נתונים ואיך מסדרים ומסננים נתונים ב-Firebase.
לפני שמתחילים
לפני שתוכלו להשתמש ב-Realtime Database, אתם צריכים:
רושמים את הפרויקט ב-Unity ומגדירים אותו לשימוש ב-Firebase.
אם הפרויקט שלכם ב-Unity כבר משתמש ב-Firebase, הוא כבר רשום ומותאם ל-Firebase.
אם אין לכם פרויקט Unity, אתם יכולים להוריד אפליקציה לדוגמה.
מוסיפים את Firebase Unity SDK (במיוחד את
FirebaseDatabase.unitypackage) לפרויקט Unity.
שימו לב שהוספת Firebase לפרויקט ב-Unity כוללת משימות שמתבצעות גם במסוף Firebase וגם בפרויקט הפתוח ב-Unity (לדוגמה, מורידים קובצי תצורה של Firebase מהמסוף ואז מעבירים אותם לפרויקט ב-Unity).
אחזור נתונים
הנתונים של Firebase מאוחזרים באמצעות קריאה חד-פעמית ל-GetValueAsync() או באמצעות צירוף לאירוע בהפניה FirebaseDatabase. הפונקציה event listener מופעלת פעם אחת עבור המצב הראשוני של הנתונים, ושוב בכל פעם שהנתונים משתנים.
קבלת DatabaseReference
כדי לקרוא נתונים ממסד הנתונים, צריך מופע של DatabaseReference:
using Firebase; using Firebase.Database; using Firebase.Extensions.TaskExtension; // for ContinueWithOnMainThread public class MyScript: MonoBehaviour { void Start() { // Get the root reference location of the database. DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference; } }
קריאת נתונים פעם אחת
אפשר להשתמש ב-method GetValueAsync כדי לקרוא תמונה סטטית של התוכן בנתיב נתון פעם אחת. תוצאת המשימה תכיל תמונת מצב עם כל הנתונים במיקום הזה, כולל נתוני צאצא. אם אין נתונים, ה-snapshot שמוחזר הוא null.
FirebaseDatabase.DefaultInstance .GetReference("Leaders") .GetValueAsync().ContinueWithOnMainThread(task => { if (task.IsFaulted) { // Handle the error... } else if (task.IsCompleted) { DataSnapshot snapshot = task.Result; // Do something with snapshot... } });
האזנה לאירועים
אתם יכולים להוסיף פונקציות event listener כדי להירשם לשינויים בנתונים:
| אירוע | שימוש אופייני |
|---|---|
ValueChanged |
קריאה והאזנה לשינויים בכל התוכן של נתיב. |
ChildAdded
| אחזור רשימות של פריטים או האזנה להוספות לרשימה של פריטים.
מומלץ להשתמש ב-ChildChanged וב-ChildRemoved כדי לעקוב אחרי שינויים ברשימות. |
ChildChanged |
חיפוש שינויים בפריטים ברשימה. אפשר להשתמש ב-ChildAdded וב-ChildRemoved כדי לעקוב אחרי שינויים ברשימות. |
ChildRemoved |
האזנה להסרת פריטים מרשימה. אפשר להשתמש ב-ChildAdded וב-ChildChanged כדי לעקוב אחרי שינויים ברשימות. |
ChildMoved |
האזנה לשינויים בסדר של פריטים ברשימה ממוספרת.
האירועים מסוג ChildMoved תמיד מופיעים אחרי האירוע מסוג ChildChanged שגרם לשינוי בסדר הפריטים (על סמך שיטת המיון הנוכחית). |
אירוע ValueChanged
אפשר להשתמש באירוע ValueChanged
כדי להירשם לשינויים בתוכן בנתיב נתון. האירוע הזה מופעל פעם אחת כשהמאזין מצורף, ושוב בכל פעם שהנתונים, כולל נתוני צאצאים, משתנים. הקריאה החוזרת (callback) של האירוע מקבלת תמונת מצב שמכילה את כל הנתונים במיקום הזה, כולל נתוני צאצא. אם אין נתונים, התמונה שמוחזרת היא null.
בדוגמה הבאה אפשר לראות משחק שמאחזר את התוצאות של טבלת המובילים ממסד הנתונים:
FirebaseDatabase.DefaultInstance .GetReference("Leaders") .ValueChanged += HandleValueChanged; } void HandleValueChanged(object sender, ValueChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot }
ValueChangedEventArgs מכיל DataSnapshot שמכיל את הנתונים במיקום שצוין במסד הנתונים בזמן האירוע. הפעלת Value
על תמונת מצב מחזירה Dictionary<string, object> שמייצג את הנתונים.
אם אין נתונים במיקום, קריאה ל-Value מחזירה null.
בדוגמה הזו, גם args.DatabaseError נבדק כדי לראות אם הקריאה בוטלה. לדוגמה, אפשר לבטל קריאה אם ללקוח אין הרשאה לקרוא ממיקום במסד נתונים של Firebase. הסיבה לכישלון תופיע בDatabaseError.
אפשר לבטל את ההרשמה לאירוע מאוחר יותר באמצעות כל DatabaseReference עם אותה נתיב. מופעי DatabaseReference הם זמניים, ואפשר לחשוב עליהם כדרך לגשת לכל נתיב ולכל שאילתה.
FirebaseDatabase.DefaultInstance .GetReference("Leaders") .ValueChanged -= HandleValueChanged; // unsubscribe from ValueChanged. }
אירועים לילדים
אירועים של צאצאים מופעלים בתגובה לפעולות ספציפיות שמתרחשות בצאצאים של צומת מפעולה, כמו צאצא חדש שנוסף באמצעות השיטה Push() או צאצא שעודכן באמצעות השיטה UpdateChildrenAsync(). כל אחת מהאפשרויות האלה יכולה להיות שימושית להאזנה לשינויים בצומת ספציפי במסד נתונים. לדוגמה, משחק יכול להשתמש בשיטות האלה ביחד כדי לעקוב אחרי הפעילות בתגובות של סשן משחק, כמו שמוצג בהמשך:
var ref = FirebaseDatabase.DefaultInstance .GetReference("GameSessionComments"); ref.ChildAdded += HandleChildAdded; ref.ChildChanged += HandleChildChanged; ref.ChildRemoved += HandleChildRemoved; ref.ChildMoved += HandleChildMoved; } void HandleChildAdded(object sender, ChildChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot } void HandleChildChanged(object sender, ChildChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot } void HandleChildRemoved(object sender, ChildChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot } void HandleChildMoved(object sender, ChildChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot }
בדרך כלל משתמשים באירוע ChildAdded כדי לאחזר רשימה של פריטים במסד נתונים של Firebase. האירוע ChildAdded מופעל פעם אחת לכל ילד קיים, ואז שוב בכל פעם שמוסיפים ילד חדש לנתיב שצוין. המאזין מקבל תמונת מצב שמכילה את הנתונים של הצאצא החדש.
האירוע ChildChanged
מופעל בכל פעם שמשנים צומת צאצא.
זה כולל שינויים בצאצאים של צומת הילד. בדרך כלל משתמשים בו בשילוב עם האירועים ChildAdded ו-ChildRemoved כדי להגיב לשינויים ברשימת פריטים. תמונת המצב שמועברת לרכיב event listener מכילה את הנתונים המעודכנים של החשבון המשני.
האירוע ChildRemoved מופעל כשמסירים צאצא ישיר.
בדרך כלל משתמשים בה בשילוב עם קריאות חוזרות (callback) של ChildAdded ו-ChildChanged. התמונה שמועברת לקריאה החוזרת של האירוע מכילה את הנתונים של צאצא שהוסר.
האירוע ChildMoved מופעל בכל פעם שהאירוע ChildChanged מופעל על ידי עדכון שגורם לסידור מחדש של הצאצא. הוא משמש עם נתונים שמסודרים לפי OrderByChild או OrderByValue.
מיון וסינון נתונים
אפשר להשתמש במחלקה Realtime Database Query כדי לאחזר נתונים ממוינים לפי מפתח, לפי ערך או לפי ערך של צאצא. אפשר גם לסנן את התוצאה הממוינת לפי מספר מסוים של תוצאות או לפי טווח של מפתחות או ערכים.
מיון נתונים
כדי לאחזר נתונים ממוינים, צריך להתחיל בציון אחת משיטות המיון כדי לקבוע את סדר התוצאות:
| שיטה | שימוש |
|---|---|
OrderByChild() |
ממיינים את התוצאות לפי הערך של מפתח צאצא ספציפי. |
OrderByKey()
| מיון התוצאות לפי מפתחות צאצא. |
OrderByValue() |
מיון התוצאות לפי ערכי צאצא. |
אפשר להשתמש רק בשיטת סידור אחת בכל פעם. קריאה לשיטת הסידור מספר פעמים באותה שאילתה גורמת לשגיאה.
בדוגמה הבאה אפשר לראות איך נרשמים לטבלת הישגים של ניקוד, שמסודרת לפי ניקוד.
FirebaseDatabase.DefaultInstance .GetReference("Leaders").OrderByChild("score") .ValueChanged += HandleValueChanged; } void HandleValueChanged(object sender, ValueChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot }
הגדרה זו מגדירה שאילתה, שכאשר משלבים אותה עם רכיב event listener מסוג valuechanged, מסנכרנת את הלקוח עם טבלת המובילים במסד הנתונים, לפי הניקוד של כל רשומה. במאמר איך מארגנים את מסד הנתונים אפשר לקרוא מידע נוסף על ארגון יעיל של הנתונים.
הקריאה ל-method OrderByChild() מציינת את מפתח הילד שבאמצעותו ימוינו התוצאות. במקרה הזה, התוצאות ממוינות לפי הערך של "score"
value בכל רכיב צאצא. מידע נוסף על הסדר של סוגי נתונים אחרים זמין במאמר איך מסודרים הנתונים בשאילתות.
סינון נתונים
כדי לסנן נתונים, אפשר לשלב כל אחת מהשיטות של הגבלה או טווח עם שיטת הסידור כשיוצרים שאילתה.
| שיטה | שימוש |
|---|---|
LimitToFirst() |
מגדיר את המספר המקסימלי של פריטים שיוחזרו מתחילת רשימת התוצאות הממוינת. |
LimitToLast() |
מגדיר את המספר המקסימלי של פריטים שיוחזרו מסוף הרשימה הממוינת של התוצאות. |
StartAt() |
הפונקציה מחזירה פריטים שגדולים מהמפתח או מהערך שצוינו או שווים להם, בהתאם לשיטת המיון שנבחרה. |
EndAt() |
הפונקציה מחזירה פריטים שקטנים מהמפתח או מהערך שצוינו או שווים להם, בהתאם לשיטת המיון שנבחרה. |
EqualTo() |
הפונקציה מחזירה פריטים ששווים למפתח או לערך שצוינו, בהתאם לשיטת המיון שנבחרה. |
בניגוד לשיטות order-by, אפשר לשלב כמה פונקציות limit או range.
לדוגמה, אפשר לשלב בין השיטות StartAt() ו-EndAt() כדי להגביל את התוצאות לטווח ערכים מסוים.
גם אם יש רק התאמה אחת לשאילתה, התמונה היא עדיין רשימה, רק שהיא מכילה פריט אחד.
הגבלת מספר התוצאות
אפשר להשתמש בשיטות LimitToFirst() ו-LimitToLast() כדי להגדיר מספר מקסימלי של צאצאים שיסונכרנו עבור קריאה חוזרת נתונה. לדוגמה, אם משתמשים ב-LimitToFirst() כדי להגדיר מגבלה של 100, מקבלים בהתחלה רק עד 100 קריאות חוזרות של ChildAdded. אם יש לכם פחות מ-100 פריטים שמאוחסנים במסד הנתונים של Firebase, מתבצעת קריאה חוזרת (callback) של ChildAdded לכל פריט.
כשהפריטים משתנים, אתם מקבלים ChildAdded קריאות חוזרות (callback) לגבי פריטים שנכנסים לשאילתה וChildRemoved קריאות חוזרות לגבי פריטים שיוצאים ממנה, כך שהמספר הכולל נשאר 100.
לדוגמה, הקוד הבא מחזיר את הציון הכי גבוה מטבלת המובילים:
FirebaseDatabase.DefaultInstance .GetReference("Leaders").OrderByChild("score").LimitToLast(1) .ValueChanged += HandleValueChanged; } void HandleValueChanged(object sender, ValueChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot }
סינון לפי מפתח או ערך
אפשר להשתמש ב-StartAt(), EndAt() ו-EqualTo() כדי לבחור נקודות שרירותיות להתחלה, לסיום ולשוויון של שאילתות.
האפשרות הזו שימושית כשרוצים להוסיף מספור לדפים של נתונים או למצוא פריטים עם פריטי צאצא שיש להם ערך ספציפי.
איך נתוני השאילתות מסודרים
בקטע הזה מוסבר איך הנתונים ממוינים לפי כל אחת מהשיטות של order-by במחלקה Query.
OrderByChild
כשמשתמשים ב-OrderByChild()
, הנתונים שמכילים את מפתח הצאצא שצוין מסודרים באופן הבא:
- ילדים עם ערך
nullלמפתח הילד שצוין מופיעים ראשונים. - אחריהם מופיעים ילדים עם הערך
falseלמפתח הצאצא שצוין. אם לכמה צאצאים יש ערך שלfalse, הם ממוינים לקסיקוגרפית לפי מפתח. - אחריהם מופיעים ילדים עם הערך
trueלמפתח הצאצא שצוין. אם לכמה צאצאים יש ערך שלtrue, הם ממוינים לפי מפתח בסדר לקסיקוגרפי. - אחריהם מופיעים ילדים עם ערך מספרי, ממוינים בסדר עולה. אם לכמה צאצאים יש את אותו ערך מספרי עבור צומת הצאצא שצוין, הם ממוינים לפי מפתח.
- מחרוזות מופיעות אחרי מספרים וממוינות בסדר עולה לפי סדר מילוני. אם לכמה צאצאים יש את אותו ערך לצומת הצאצא שצוין, הם מסודרים לפי מפתח בסדר לקסיקוגרפי.
- האובייקטים מופיעים בסוף וממוינים בסדר עולה לפי מפתח, בסדר לקסיקוגרפי.
OrderByKey
כשמשתמשים ב-OrderByKey() כדי למיין את הנתונים, הנתונים מוחזרים בסדר עולה לפי מפתח.
- הילדים עם מפתח שאפשר לנתח כמספר שלם בן 32 ביט מופיעים ראשונים, בסדר עולה.
- אחרי כן מופיעים ילדים עם ערך מחרוזת כמפתח, ממוינים בסדר עולה לפי סדר מילוני.
OrderByValue
כשמשתמשים ב-OrderByValue(), הילדים מסודרים לפי הערך שלהם. קריטריוני המיון זהים לאלה שמופיעים ב-OrderByChild(), אלא שהערך של הצומת משמש במקום הערך של מפתח צאצא ספציפי.