Skip to content
This repository was archived by the owner on Aug 20, 2025. It is now read-only.

Commit 3f0a81e

Browse files
authored
Merge pull request #14 from dzlier-gcp/master
Add protection to creating scores from DataSnapshots.
2 parents c708ddb + 6b90970 commit 3f0a81e

File tree

4 files changed

+49
-20
lines changed

4 files changed

+49
-20
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
LICENSE.meta

Firebase_Leaderboard/Scripts/LeaderboardController.cs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ private void Update() {
262262

263263
dbref = FirebaseDatabase.DefaultInstance.RootReference;
264264
initialized = true;
265-
RefreshScores();
265+
refreshScores = true;
266266
readyToInitialize = false;
267267
if (FirebaseInitialized != null) {
268268
FirebaseInitialized(this, null);
@@ -427,6 +427,7 @@ public Task<UserScore> AddScore(UserScore score) {
427427
return newEntry.SetValueAsync(scoreDict).ContinueWith(task => {
428428
if (task.Exception != null) {
429429
Debug.LogWarning("Exception adding score: " + task.Exception);
430+
return null;
430431
}
431432
if (!task.IsCompleted) {
432433
return null;
@@ -508,7 +509,10 @@ private void OnScoreAdded(object sender, ChildChangedEventArgs args) {
508509
return;
509510
}
510511

511-
var score = new UserScore(args.Snapshot);
512+
var score = UserScore.CreateScoreFromRecord(args.Snapshot);
513+
if (score == null) {
514+
return;
515+
}
512516

513517
// Verify that score is within start/end times, and isn't already in TopScores.
514518
if (TopScores.Contains(score)) {
@@ -577,7 +581,10 @@ private void OnScoreRemoved(object sender, ChildChangedEventArgs args) {
577581
if (args.Snapshot == null || !args.Snapshot.Exists) {
578582
return;
579583
}
580-
var score = new UserScore(args.Snapshot);
584+
var score = UserScore.CreateScoreFromRecord(args.Snapshot);
585+
if (score == null) {
586+
return;
587+
}
581588
if (TopScores.Contains(score)) {
582589
TopScores.Remove(score);
583590
RefreshScores();
@@ -609,7 +616,7 @@ private void GetInitialTopScores(long batchEnd) {
609616
return;
610617
}
611618

612-
if (task.Result.ChildrenCount == 0) {
619+
if (!task.Result.HasChildren) {
613620
// No scores left to retrieve.
614621
SetTopScores();
615622
return;
@@ -630,19 +637,20 @@ private void GetInitialTopScores(long batchEnd) {
630637

631638
// Until we have found ScoresToRetrieve unique user scores or run out of
632639
// scores to retrieve, get another page of score records by ending the next batch
633-
// (ordered by score) at the lowest score found so far.
634-
var lastScore = task.Result.Children.First().Child("score").GetRawJsonValue();
635-
long score, nextEndAt;
640+
// (ordered by score) at the worst score found so far.
641+
long nextEndAt;
636642
if (LowestFirst) {
637-
nextEndAt = Int64.TryParse(lastScore, out score) ?
638-
score + 1 :
639-
Math.Min(Int64.MaxValue, batchEnd + 1);
643+
nextEndAt = scores.First().Score + 1L;
640644
} else {
641-
nextEndAt = Int64.TryParse(lastScore, out score) ?
642-
score - 1 :
643-
Math.Max(Int64.MinValue, batchEnd - 1);
645+
nextEndAt = scores.Last().Score - 1L;
646+
}
647+
try {
648+
GetInitialTopScores(nextEndAt);
649+
} catch (Exception ex) {
650+
Debug.LogException(ex);
651+
} finally {
652+
SetTopScores();
644653
}
645-
GetInitialTopScores(nextEndAt);
646654
});
647655
}
648656

@@ -653,15 +661,16 @@ private void GetInitialTopScores(long batchEnd) {
653661
/// <param name="snapshot">DataSnapshot record of user scores.</param>
654662
/// <param name="startTS">Earliest valid timestamp of a user score to retrieve.</param>
655663
/// <param name="endTS">Latest valid timestamp of a user score to retrieve.</param>
656-
/// <returns>IEnumerable of valid UserScore objects.</returns>
657-
private IEnumerable<UserScore> ParseValidUserScoreRecords(
664+
/// <returns>List of valid UserScore objects.</returns>
665+
private List<UserScore> ParseValidUserScoreRecords(
658666
DataSnapshot snapshot,
659667
long startTS,
660668
long endTS) {
661669
return snapshot.Children
662-
.Select(scoreRecord => new UserScore(scoreRecord))
663-
.Where(score => score.Timestamp > startTS && score.Timestamp <= endTS)
664-
.Reverse();
670+
.Select(scoreRecord => UserScore.CreateScoreFromRecord(scoreRecord))
671+
.Where(score => score != null && score.Timestamp > startTS && score.Timestamp <= endTS)
672+
.Reverse()
673+
.ToList();
665674
}
666675

667676
/// <summary>

Firebase_Leaderboard/Scripts/UserScore.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
using System;
1818
using System.Collections.Generic;
1919
using Firebase.Database;
20+
using UnityEngine;
2021

2122
namespace Firebase.Leaderboard {
2223
/// <summary>
@@ -52,6 +53,24 @@ public string ShortDateString {
5253
}
5354
}
5455

56+
/// <summary>
57+
/// If record contains required score fields, create a new UserScore from it.
58+
/// If not, return null.
59+
/// </summary>
60+
/// <param name="record">The score record object from Firebase Database.</param>
61+
public static UserScore CreateScoreFromRecord(DataSnapshot record) {
62+
if (record == null) {
63+
Debug.LogWarning("Null DataSnapshot record in UserScore.CreateScoreFromRecord.");
64+
return null;
65+
}
66+
if (record.Child(UserIDPath).Exists && record.Child(ScorePath).Exists &&
67+
record.Child(TimestampPath).Exists) {
68+
return new UserScore(record);
69+
}
70+
Debug.LogWarning("Invalid record format in UserScore.CreateScoreFromRecord.");
71+
return null;
72+
}
73+
5574
/// <summary>
5675
/// Construct a UserScore manually from a User ID, score value, and timestamp.
5776
/// </summary>
@@ -91,7 +110,7 @@ public UserScore(
91110
/// Reconstruct a UserScore from a DataSnapshot record retrieved from Firebase Database.
92111
/// </summary>
93112
/// <param name="record">The score record object from Firebase Database.</param>
94-
public UserScore(DataSnapshot record) {
113+
private UserScore(DataSnapshot record) {
95114
UserID = record.Child(UserIDPath).Value.ToString();
96115
if (record.Child(UsernamePath).Exists) {
97116
Username = record.Child(UsernamePath).Value.ToString();
14.5 KB
Binary file not shown.

0 commit comments

Comments
 (0)