לשמור מידע

לפני שאתה מתחיל

לפני שתוכל להשתמש במסד נתונים בזמן אמת , עליך:

  • רשום את פרויקט Unity שלך והגדר אותו לשימוש ב-Firebase.

    • אם פרויקט Unity שלך כבר משתמש ב-Firebase, אז הוא כבר רשום ומוגדר עבור Firebase.

    • אם אין לך פרויקט של Unity, תוכל להוריד אפליקציה לדוגמה .

  • הוסף את Firebase Unity SDK (באופן ספציפי, FirebaseDatabase.unitypackage ) לפרויקט Unity שלך.

שים לב שהוספת Firebase לפרויקט Unity שלך כרוכה במשימות הן במסוף Firebase והן בפרויקט Unity הפתוח (לדוגמה, אתה מוריד קובצי תצורה של Firebase מהמסוף, ואז מעביר אותם לפרויקט Unity שלך).

שמירת נתונים

ישנן חמש שיטות לכתיבת נתונים למסד הנתונים בזמן אמת של Firebase:

שיטה שימושים נפוצים
SetValueAsync() כתוב או החלף נתונים לנתיב מוגדר, כגון users/<user-id>/<username> .
SetRawJsonValueAsync() כתוב או החלף נתונים ב-Json גולמי, כגון users/<user-id>/<username> .
Push() הוסף לרשימת נתונים. בכל פעם שאתה קורא ל- Push() , Firebase מייצר מפתח ייחודי שיכול לשמש גם כמזהה ייחודי, כגון user-scores/<user-id>/<unique-score-id> .
UpdateChildrenAsync() עדכן חלק מהמפתחות עבור נתיב מוגדר מבלי להחליף את כל הנתונים.
RunTransaction() עדכן נתונים מורכבים שעלולים להיפגם על ידי עדכונים במקביל.

קבל הפניית מסד נתונים

כדי לכתוב נתונים למסד הנתונים, אתה צריך מופע של DatabaseReference :

using Firebase;
using Firebase.Database;

public class MyScript: MonoBehaviour {
  void Start() {
    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

כתוב, עדכן או מחק נתונים בהפניה

פעולות כתיבה בסיסיות

עבור פעולות כתיבה בסיסיות, אתה יכול להשתמש SetValueAsync() כדי לשמור נתונים בהפניה שצוינה, תוך החלפת כל הנתונים הקיימים בנתיב זה. אתה יכול להשתמש בשיטה זו כדי להעביר סוגים התואמים לסוגי JSON הזמינים באופן הבא:

  • string
  • long
  • double
  • bool
  • Dictionary<string, Object>
  • List<Object>

אם אתה משתמש באובייקט C# מוקלד, אתה יכול להשתמש ב- JsonUtility.ToJson() המובנה כדי להמיר את האובייקט ל-Json גולמי ולקרוא ל- SetRawJsonValueAsync() . לדוגמה, ייתכן שיש לך מחלקה User שנראתה כך:

public class User {
    public string username;
    public string email;

    public User() {
    }

    public User(string username, string email) {
        this.username = username;
        this.email = email;
    }
}

אתה יכול להוסיף משתמש עם SetRawJsonValueAsync() באופן הבא:

private void writeNewUser(string userId, string name, string email) {
    User user = new User(name, email);
    string json = JsonUtility.ToJson(user);

    mDatabaseRef.Child("users").Child(userId).SetRawJsonValueAsync(json);
}

שימוש SetValueAsync() או SetRawJsonValueAsync() באופן זה מחליף נתונים במיקום שצוין, כולל כל צמתים צאצאים. עם זאת, אתה עדיין יכול לעדכן ילד מבלי לשכתב את כל האובייקט. אם אתה רוצה לאפשר למשתמשים לעדכן את הפרופילים שלהם, תוכל לעדכן את שם המשתמש באופן הבא:

mDatabaseRef.Child("users").Child(userId).Child("username").SetValueAsync(name);

הוסף לרשימת נתונים

השתמש בשיטת Push() כדי להוסיף נתונים לרשימה ביישומים מרובי משתמשים. השיטה Push() יוצרת מפתח ייחודי בכל פעם שילד חדש מתווסף להפניה שצוינה ב-Firebase. על ידי שימוש במפתחות אלה שנוצרו אוטומטית עבור כל רכיב חדש ברשימה, מספר לקוחות יכולים להוסיף ילדים לאותו מיקום בו-זמנית ללא התנגשויות כתיבה. המפתח הייחודי שנוצר על ידי Push() מבוסס על חותמת זמן, ולכן פריטי רשימה מסודרים באופן אוטומטי באופן כרונולוגי.

אתה יכול להשתמש בהפניה לנתונים החדשים המוחזרים על ידי שיטת Push() כדי לקבל את הערך של המפתח שנוצר אוטומטית של הילד או להגדיר נתונים עבור הילד. קריאת Key בהפניה Push() מחזירה את הערך של המפתח שנוצר אוטומטית.

עדכן שדות ספציפיים

כדי לכתוב בו-זמנית לילדים ספציפיים של צומת מבלי לדרוס צמתים צאצאים אחרים, השתמש בשיטת UpdateChildrenAsync() .

בעת קריאה ל- UpdateChildrenAsync() , תוכל לעדכן ערכי צאצא ברמה נמוכה יותר על ידי ציון נתיב עבור המפתח. אם הנתונים מאוחסנים במספר מיקומים כדי להרחיב את גודלם טוב יותר, אתה יכול לעדכן את כל המופעים של נתונים אלה באמצעות מניפת נתונים . לדוגמה, למשחק עשויה להיות שיעור LeaderboardEntry כמו זה:

public class LeaderboardEntry {
    public string uid;
    public int score = 0;

    public LeaderboardEntry() {
    }

    public LeaderboardEntry(string uid, int score) {
        this.uid = uid;
        this.score = score;
    }

    public Dictionary<string, Object> ToDictionary() {
        Dictionary<string, Object> result = new Dictionary<string, Object>();
        result["uid"] = uid;
        result["score"] = score;

        return result;
    }
}

כדי ליצור LeaderboardEntry ולעדכן אותו בו-זמנית לעדכון הניקוד האחרון ולרשימת הניקוד של המשתמש עצמו, המשחק משתמש בקוד כך:

private void WriteNewScore(string userId, int score) {
    // Create new entry at /user-scores/$userid/$scoreid and at
    // /leaderboard/$scoreid simultaneously
    string key = mDatabase.Child("scores").Push().Key;
    LeaderBoardEntry entry = new LeaderBoardEntry(userId, score);
    Dictionary<string, Object> entryValues = entry.ToDictionary();

    Dictionary<string, Object> childUpdates = new Dictionary<string, Object>();
    childUpdates["/scores/" + key] = entryValues;
    childUpdates["/user-scores/" + userId + "/" + key] = entryValues;

    mDatabase.UpdateChildrenAsync(childUpdates);
}

דוגמה זו משתמשת ב- Push() כדי ליצור ערך בצומת המכיל ערכים עבור כל המשתמשים ב- /scores/$key ובו-זמנית לאחזר את המפתח עם Key . לאחר מכן ניתן להשתמש במפתח ליצירת ערך שני בציוני המשתמש ב- /user-scores/$userid/$key .

באמצעות נתיבים אלה, תוכל לבצע עדכונים בו-זמנית למספר מיקומים בעץ ה-JSON עם קריאה בודדת ל- UpdateChildrenAsync() , כגון האופן שבו דוגמה זו יוצרת את הערך החדש בשני המיקומים. עדכונים בו-זמניים שנעשו בדרך זו הם אטומיים: או שכל העדכונים מצליחים או שכל העדכונים נכשלים.

מחק נתונים

הדרך הפשוטה ביותר למחוק נתונים היא לקרוא ל- RemoveValue() בהפניה למיקום הנתונים הללו.

אתה יכול גם למחוק על ידי ציון null כערך עבור פעולת כתיבה אחרת כגון SetValueAsync() או UpdateChildrenAsync() . אתה יכול להשתמש בטכניקה זו עם UpdateChildrenAsync() כדי למחוק ילדים מרובים בקריאה אחת ל-API.

דע מתי הנתונים שלך מחויבים.

כדי לדעת מתי הנתונים שלך מחויבים לשרת Firebase Realtime Database, אתה יכול להוסיף המשך. גם SetValueAsync() וגם UpdateChildrenAsync() מחזירים Task המאפשרת לך לדעת מתי הפעולה הושלמה. אם השיחה לא מצליחה מסיבה כלשהי, ה-Tasks IsFaulted יהיו נכונים כאשר המאפיין Exception מציין מדוע הכשל התרחש.

שמור נתונים כעסקאות

כשאתה עובד עם נתונים שעלולים להיפגם על ידי שינויים בו-זמניים, כגון מונים מצטברים, אתה יכול להשתמש בפעולת עסקה . אתה נותן לפעולה זו Func . עדכון זה Func לוקח את המצב הנוכחי של הנתונים כארגומנט ומחזיר את המצב הרצוי החדש שתרצה לכתוב. אם לקוח אחר כותב למיקום לפני שהערך החדש שלך נכתב בהצלחה, פונקציית העדכון שלך נקראת שוב עם הערך הנוכחי החדש, והכתיבה מתבצעת מחדש.

לדוגמה, במשחק אתה יכול לאפשר למשתמשים לעדכן טבלת הישגים עם חמשת הציונים הגבוהים ביותר:

private void AddScoreToLeaders(string email, 
                               long score,
                               DatabaseReference leaderBoardRef) {

    leaderBoardRef.RunTransaction(mutableData => {
      List<object> leaders = mutableData.Value as List<object>

      if (leaders == null) {
        leaders = new List<object>();
      } else if (mutableData.ChildrenCount >= MaxScores) {
        long minScore = long.MaxValue;
        object minVal = null;
        foreach (var child in leaders) {
          if (!(child is Dictionary<string, object>)) continue;
          long childScore = (long)
                      ((Dictionary<string, object>)child)["score"];
          if (childScore < minScore) {
            minScore = childScore;
            minVal = child;
          }
        }
        if (minScore > score) {
          // The new score is lower than the existing 5 scores, abort.
          return TransactionResult.Abort();
        }

        // Remove the lowest score.
        leaders.Remove(minVal);
      }

      // Add the new high score.
      Dictionary<string, object> newScoreMap =
                       new Dictionary<string, object>();
      newScoreMap["score"] = score;
      newScoreMap["email"] = email;
      leaders.Add(newScoreMap);
      mutableData.Value = leaders;
      return TransactionResult.Success(mutableData);
    });
}

שימוש בטרנזקציה מונע מלוח ההישגים להיות שגוי אם מספר משתמשים רושמים ציונים בו-זמנית או שללקוח היו נתונים מיושנים. אם העסקה נדחתה, השרת מחזיר את הערך הנוכחי ללקוח, אשר מריץ את העסקה שוב עם הערך המעודכן. זה חוזר על עצמו עד שהעסקה מתקבלת או שנעשו יותר מדי ניסיונות.

כתוב נתונים במצב לא מקוון

אם לקוח מאבד את חיבור הרשת שלו, האפליקציה שלך תמשיך לפעול כהלכה.

כל לקוח המחובר למסד נתונים של Firebase שומר על גרסה פנימית משלו של כל נתונים פעילים. כאשר נתונים נכתבים, הם נכתבים תחילה לגרסה המקומית הזו. לאחר מכן, לקוח Firebase מסנכרן את הנתונים האלה עם שרתי מסד הנתונים המרוחקים ועם לקוחות אחרים על בסיס "המאמץ הטוב ביותר".

כתוצאה מכך, כל הכתיבה למסד הנתונים מפעילה אירועים מקומיים באופן מיידי, לפני כל כתיבה של נתונים לשרת. משמעות הדבר היא שהאפליקציה שלך נשארת מגיבה ללא קשר לאחזור הרשת או הקישוריות.

ברגע שהקישוריות מתבססת מחדש, האפליקציה שלך מקבלת את סט האירועים המתאים כך שהלקוח מסתנכרן עם מצב השרת הנוכחי, ללא צורך בכתיבת קוד מותאם אישית.

הצעדים הבאים