2017-07-05 73 views
0

我正在構建Unity3d 2D遊戲,並將Firebase作爲數據庫使用。我需要在數據庫中存儲相當多的DateTime值(作爲UTC),我想知道做這件事的最佳做法是什麼。使用Unity3d在Firebase中存儲DateTime值的最佳做法

DateTime字段將主要用於排序/過濾。

按照火力地堡的文件,我應該利用Firebase.Database.ServerValues.TIMESTAMP這僅僅是一個object

的事情是,我使用的是強類型的模型,我團結的遊戲,像這樣的:

[Serializable] 
public class Profile { 

    [NonSerialized] 
    public string ProfileKey; 

    // Serializable attributes 
    public string userId; 
    public string name; 
    public int age; 
    public string gender; // "M" or "F" 
    public DateTime utcCreated; // UTC 
    public DateTime utcUpdated; // UTC 
} 

和我使用Unitys JsonUtility.ToJson()方法,這樣當我保存/更新Profile

var profiles = db.Child ("profiles"); 

Profile profile = new Profile { 
    userId = GameManager.Instance.User.UserId, 
    name = "My new profile", 
    age = 23, 
    gender = "M", 
    utcCreated = ?? // Should somehow use Firebase.Database.ServerValues.TIMESTAMP here, I guess? 
};    

string json = JsonUtility.ToJson (profile);  

var profileKey = profiles.Push().Key; 

profiles.Child (profileKey).SetRawJsonValueAsync (json, 1).ContinueWith (t => { 
    // .. handle response here 
}); 

我不確定我應該在我的模型上設置utcCreated字段。試圖簡單地將該字段設置爲object,但沒有值插入到Firebase中。還嘗試將其設爲.ToString()Firebase.Database.ServerValues.TIMESTAMP對象的字符串,但未在Firebase中插入任何值。

有沒有人有一個想法如何做到這一點? ;-)或者只是關於在Firebase中存儲日期和時間戳的最佳做法的任何幫助/提示?

在此先感謝。

回答

0

好吧,對於這個問題誰不想花小時的頭髮拉沮喪的人,答案是:你不能(也許不應該,猜猜這是有原因的)設置ServerValue.Timestamp對象你的模型/對象。

ServerValue.Timestamp是值得您特別通過調用SetValueAsync()UpdateChildrenAsync()

你的火力地堡文件設定所以我做了什麼,是添加兩個領域我Profile類:一個代表Unix時間戳服務器值和一個,它代表了Unix時間戳服務器值作爲C#DateTime對象:

using System; 
using System.Collections.Generic; 
using System.Linq; 

[Serializable] 
public class Profile 
{ 

    [NonSerialized] 
    public string profileKey; 

    [NonSerialized] 
    public long utcCreatedTimestamp; 

    [NonSerialized] 
    public DateTime utcCreated; 

    // Serializable attributes 
    public string userId; 
    public string name; 
    public int age; 
    public string gender; // "M" or "F" 

    public Profile() { } 

    public Profile(Dictionary<string, object> fromFirebaseResult) 
    { 
     userId = fromFirebaseResult.ContainsKey("userId") ? fromFirebaseResult.First(x => x.Key == "userId").Value.ToString() : string.Empty; 
     name = fromFirebaseResult.ContainsKey("name") ? fromFirebaseResult.First(x => x.Key == "name").Value.ToString() : string.Empty; 
     age = fromFirebaseResult.ContainsKey("age") ? int.Parse(fromFirebaseResult.First(x => x.Key == "age").Value.ToString()) : 0; 
     gender = fromFirebaseResult.ContainsKey("gender") ? fromFirebaseResult.First(x => x.Key == "gender").Value.ToString() : string.Empty; 

     if (fromFirebaseResult.ContainsKey("utcCreatedUnix")) { 
      long milliseconds; 
      if(long.TryParse(fromFirebaseResult.First(x => x.Key == "utcCreatedUnix").Value.ToString(), out milliseconds)) { 
       utcCreatedTimestamp = milliseconds; 

       DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 

       utcCreated = epoch.AddMilliseconds(milliseconds); 
      } 
     } 
    } 
} 

Profile類都有一個默認的構造和構造,這需要一個Dictionary<string, object>罪這就是我們在從Unity查詢時從Firebase獲得的信息。

將新的Profile保存到Firebase時,我創建了一個新的對象Profile,但未設置與日期和時間相關的任何內容。將其保存在Firebase中,然後致電UpdateChildrenAsync,在Firebase中設置utcCreatedUnix字段。像這樣:

DatabaseReference db = FirebaseDatabase.DefaultInstance.RootReference; 

// Get the user id 
string userId = GameManager.Instance.User.UserId; 

// Get a reference to the profiles 
var profiles = db.Child("profiles"); 

// Create a new serializable profile 
Profile profile = new Profile { 
    userId = userId, 
    name = "Bo Mortensen", 
    age = 34, 
    gender = "M" 
};    

// Serialize profile to JSON 
string json = JsonUtility.ToJson (profile);  

// Push a new document to the database 
var profileKey = profiles.Push().Key; 

// Set JSON for this document 
profiles.Child (profileKey).SetRawJsonValueAsync (json, 1).ContinueWith (t => { 
    if (t.IsCompleted) { 
     // Assign the profile key (unique key generated by Firebase) to the profile 
     profile.profileKey = profileKey; 

     // Set the Firebase server timestamp on the datetime object 
     profiles.Child(profileKey).UpdateChildrenAsync(new Dictionary<string, object> { { "utcCreatedUnix", ServerValue.Timestamp } }); 
    } 
}); 

而且從火力地堡得到一個Profile文檔時,我現在可以做的事:

var db = FirebaseDatabase.DefaultInstance.RootReference; 

var profileRef = db.Child("profiles/MyProfileKey"); 

profileRef.GetValueAsync().ContinueWith(t => 
{ 
    var values = t.Result.Value as System.Collections.Generic.Dictionary<string, object>; 

    // Let the constructor populate the fields 
    Profile profile = new Profile(values) 
    { 
     profileKey = profileRef.Key 
    }; 


    DateTime createdDate = profile.utcCreated; 
}); 

你可能會問爲什麼我不只是存儲DateTime.UtcNow.ToString()我能做到這一點,但我不想依賴客戶端時鐘設置。通過使用Firebases ServerValue.Timestamp,Firebase將確定正確的時間,而不是使用應用程序的單個客戶端。

希望這可以幫助其他任何人:-)

相關問題