C# 如何使用Firebase实时数据库使用排行榜更新用户ID,
我正在使用Transaction通过Unity3D和实时数据库保存领导委员会分数。 我的最终目标是:C# 如何使用Firebase实时数据库使用排行榜更新用户ID,,c#,firebase,unity3d,firebase-realtime-database,C#,Firebase,Unity3d,Firebase Realtime Database,我正在使用Transaction通过Unity3D和实时数据库保存领导委员会分数。 我的最终目标是: 查找数据库排行榜中是否已存在UserID 如果UserID存在,则检查新分数(来自游戏)是否更高 比旧分数高(来自数据库),如果是,则删除旧分数并放置新分数 如果UserID不存在,则只需添加更高的新分数即可 而不是整个数据库列表的最低分数。下面的代码示例显示了它现在的功能 我想到的一种方法是按score对列表进行排序,这样我就可以一个接一个地传递整个列表并找到userID位置和分数,然后以某
UserID
UserID
存在,则检查新分数(来自游戏)是否更高
比旧分数高(来自数据库),如果是,则删除旧分数并放置新分数UserID
不存在,则只需添加更高的新分数即可
而不是整个数据库列表的最低分数。下面的代码示例显示了它现在的功能score
对列表进行排序,这样我就可以一个接一个地传递整个列表并找到userID位置和分数,然后以某种方式删除找到的userID并放置新分数
我试着对它进行分类,但似乎没有什么能让分类在这里起作用
毫无疑问,这是一个棘手的问题
代码:
TransactionResult AddScoreTransaction(可变数据可变数据){
列表引线=可变数据。值为列表;
if(leaders==null){
领导者=新列表();
}else if(mutableData.ChildrenCount>=MaxScores){
//如果当前的分数列表大于或等于我们允许的最大分数,
//我们看看是否应该添加新的分数并删除现有的最低分数。
long minScore=long.MaxValue;
object minVal=null;
foreach(领导者中的var子级){
如果(!(儿童是字典))
继续;
long childScore=(long)((字典)child)[“score”];
if(儿童分数score){
返回TransactionResult.Abort();
}
//否则,我们将删除当前的最低分数,并将其替换为新分数。
领导者。移除(minVal);
}
//现在,我们将新分数添加为包含电子邮件地址和分数的新条目。
Dictionary newScoreMap=新字典();
newScoreMap[“分数”]=分数;
newScoreMap[“电子邮件”]=电子邮件;
newScoreMap[“userId”]=userId;
添加(newScoreMap);
//必须设置该值以指示该位置的数据已更改。
mutableData.Value=leaders;
返回TransactionResult.Success(可变数据);
}
公共无效AddScore(){
如果(分数==0 | | string.IsNullOrEmpty(电子邮件)){
调试日志(“无效分数或电子邮件”);
返回;
}
DebugLog(String.Format(“试图添加分数{0}{1}”,email,score.ToString());
DatabaseReference=FirebaseDatabase.DefaultInstance.GetReference(“领导者”).Child(“ClassA”);
调试日志(“正在运行的事务…”);
//使用事务来确保我们不会遇到与
//同时更新,否则可能会创建超过MaxScores top scores的分数。
reference.RunTransaction(AddScoreTransaction)
.ContinueWith(任务=>{
if(task.Exception!=null){
调试日志(task.Exception.ToString());
}else if(任务已完成){
调试日志(“事务完成”);
}
});
}
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.");
}
});
}