我正在使用Transaction来通过Unity3D和RealTime数据库保存排行榜得分。 我的最终目标是:
UserID
是否已存在于数据库排行榜中
。UserID
,则检查(来自游戏)的新分数是否更高
比旧分数(来自数据库)要大的话,如果删除,请删除旧分数并放置新分数。UserID
不存在,则添加新分数(如果更高)
比整个数据库列表中最低的分数高。 现在从下面的代码示例中所做的几乎是什么。 我想到的一种方法是按score
对列表进行排序,然后我就可以逐个传递整个列表并找到userID的位置和得分,然后以某种方式删除找到的userID并放置新的得分。
我试图对其进行排序,但是似乎没有任何东西可以在这里进行排序。
毫无疑问,这是一个棘手的问题。
代码:
TransactionResult AddScoreTransaction(MutableData mutableData) {
List<object> leaders = mutableData.Value as List<object>;
if (leaders == null) {
leaders = new List<object>();
} else if (mutableData.ChildrenCount >= MaxScores) {
// If the current list of scores is greater or equal to our maximum allowed number,
// we see if the new score should be added and remove the lowest existing score.
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 the new score is lower than the current minimum, we abort.
if (minScore > score) {
return TransactionResult.Abort();
}
// Otherwise, we remove the current lowest to be replaced with the new score.
leaders.Remove(minVal);
}
// Now we add the new score as a new entry that contains the email address and score.
Dictionary<string, object> newScoreMap = new Dictionary<string, object>();
newScoreMap["score"] = score;
newScoreMap["email"] = email;
newScoreMap["userId"] = userId;
leaders.Add(newScoreMap);
// You must set the Value to indicate data at that location has changed.
mutableData.Value = leaders;
return TransactionResult.Success(mutableData);
}
public void AddScore() {
if (score == 0 || string.IsNullOrEmpty(email)) {
DebugLog("invalid score or email.");
return;
}
DebugLog(String.Format("Attempting to add score {0} {1}", email, score.ToString()));
DatabaseReference reference = FirebaseDatabase.DefaultInstance.GetReference("Leaders").Child("ClassA");
DebugLog("Running Transaction...");
// Use a transaction to ensure that we do not encounter issues with
// simultaneous updates that otherwise might create more than MaxScores top scores.
reference.RunTransaction(AddScoreTransaction)
.ContinueWith(task => {
if (task.Exception != null) {
DebugLog(task.Exception.ToString());
} else if (task.IsCompleted) {
DebugLog("Transaction complete.");
}
});
}