question

Kim Strasser avatar image
Kim Strasser asked

Issue with updating leaderboard in CloudScript

I get an error message when I want to update my leaderboard in CloudScript:

"apiError": {
            "code": 400,
            "status": "BadRequest",
            "error": "InvalidParams",
            "errorCode": 1000,
            "errorMessage": "Invalid input parameters",
            "errorHash": null,
            "errorDetails": {
                            "Statistics": [
                                "The Statistics field is required."
                            ]
            }

Is something wrong with this code?

 var result = server.UpdatePlayerStatistics({
           PlayFabId: currentPlayerId,
           Statistics : { StatisticName : leaderboardname, Value : score }
        });

In addition, how can I get the player’s highscore in CloudScript when I call server.GetLeaderboard? I don't know how to get the highscore from resultleaderboard in CloudScript.

if ((resultleaderboard != null) && (resultleaderboard.Error == null))
    return "Your highscore: " + resultleaderboard.;

CloudScript:

handlers.UpdateLeaderboard = function (args, context)
{
 var AddScore = UpdatePlayerScore(args.Leaderboardname, args.Playerscore);
 
    if (AddScore.leaderboardupdated == true)
       log.info("User statistics updated.");
    else
       log.info("Could not update statistics.");
  
    var resultleaderboard = server.GetLeaderboard(
        {
            PlayFabID: currentPlayerId,
            StatisticName : args.Leaderboardname,
            ProfileConstraints: {
                ShowDisplayName : true
            }
        });
        
    //How can I get the player's highscore?
    if ((resultleaderboard != null) && (resultleaderboard.Error == null))
        return "Your highscore: ...";
    else
        return "Something went wrong. Could not get leaderboard highscore."
}

function UpdatePlayerScore(leaderboardname, score)
{
      var result = server.UpdatePlayerStatistics({
           PlayFabId: currentPlayerId,
           Statistics : { StatisticName : leaderboardname, Value : score }
        });
        
       if (result.Error == null)
           return { leaderboardupdated: true };
       else
           return { leaderboardupdated: false };
}

Client code:

private async Task UpdatePlayerHighscore(string leaderboardname, string playerscore)
{
    var result = await PlayFabClientAPI.ExecuteCloudScriptAsync(new ExecuteCloudScriptRequest()
    {
        FunctionName = "UpdateLeaderboard",
        FunctionParameter = new { Leaderboardname = leaderboardname, playerscore },
        GeneratePlayStreamEvent = true
    });

    if (result.Error != null)
        Console.WriteLine(result.Error.Error.ToString());
    else
    {
        if (result.Result.Logs.Count() > 0)
            Console.WriteLine(result.Result.Logs[0].Message);
        if (result.Result.FunctionResult != null)
            Console.WriteLine(result.Result.FunctionResult);
    }
}
CloudScript
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
Seth Du avatar image
Seth Du answered

I haven't fully tested your code but there is an obvious typo issue on your code:

 var result = server.UpdatePlayerStatistics({
           PlayFabId: currentPlayerId,
           Statistics : { StatisticName : leaderboardname, Value : score }
        });

If you check the official documentation, the Statistics Property is a list of StatisticUpdate, meanwhile in your request, there is only one StatisticUpdate object in Statistics property.

Hence, please replace the request code with the following:

 var result = server.UpdatePlayerStatistics({
           PlayFabId: currentPlayerId,
           Statistics :[{ StatisticName : leaderboardname, Value : score }]
        });

Another offical sample on our Postman collection is:

{
  "PlayFabId": "{
                {PlayFabId}}",
  "Statistics": [
    {
      "StatisticName": "Points",
      "Version": 1,
      "Value": 600
    },
    {
      "StatisticName": "Wins",
      "Version": 2,
      "Value": 16
    },
    {
      "StatisticName": "Stars",
      "Value": 7
    }
  ]
}
<br>

Moreover, "Invalid input parameters" often occurs when the request property is not well-formatted, we usually check the properties' types in the documentation to debug.

5 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Kim Strasser avatar image Kim Strasser commented ·

Thanx. It works with:

Statistics :[{ StatisticName : leaderboardname, Value : score }]

But I have another issue when I want to get the player's score from the leaderboard. I get this exception:

"Error": {
            "Error": "JavascriptException",
            "Message": "JavascriptException",
            "StackTrace": "TypeError: Cannot read property 'Leaderboard' of undefined\n    at handlers.UpdateLeaderboard (BFD0A-main.js:872:34)\n    at Object.invokeFunction (Script:116:33)"
        }

How can I get the player's display name and the score in CloudScript?

var resultleaderboard = server.GetLeaderboard(
{
  PlayFabID: currentPlayerId,
  StatisticName : args.Leaderboardname,
  MaxResultsCount : 100,
  ProfileConstraints: {
  ShowDisplayName : true
  }
});
        
if ((resultleaderboard != null) && (resultleaderboard.Error == null))
{
  resultleaderboard.result.Leaderboard.forEach(element => {
      if (element.PlayFabId == currentPlayerId)
      {
          CurrentScore = element.Profile.DisplayName + " : " + element.entry.StatValue.toString();
          return;
      }
  });
}
else
  CurrentScore = "Something went wrong. Could not get leaderboard highscore.";

return CurrentScore;
0 Likes 0 ·
Seth Du avatar image Seth Du ♦ Kim Strasser commented ·

I think you may replace this line:

resultleaderboard.result.Leaderboard.forEach(...

with

resultleaderboard.Leaderboard.forEach(...

Besides, I am not sure if there will be additional actions you may do in the forEach() loop, but if locating the current player is the only thing you require doing, you may use GetLeaderboardAroundUser while set the MaxResultsCount as 1 in the request.

0 Likes 0 ·
Kim Strasser avatar image Kim Strasser Seth Du ♦ commented ·

Ok, I will use GetLeaderboardAroundUser.

I get another error:

"Error": {
            "Error": "JavascriptException",
            "Message": "JavascriptException",
            "StackTrace": "TypeError: Cannot read property 'StatValue' of undefined\n    at BFD0A-main.js:885:81\n    at Array.forEach (<anonymous>)\n    at handlers.UpdateLeaderboard (BFD0A-main.js:882:39)\n    at Object.invokeFunction (Script:116:33)"       
var resultleaderboard = server.GetLeaderboardAroundUser(
{
    PlayFabID: currentPlayerId,
    StatisticName : args.Leaderboardname,
    MaxResultsCount : 1,
    ProfileConstraints: {
    ShowDisplayName : true
    }
});

 if ((resultleaderboard != null) && (resultleaderboard.Error == null))
    {
        resultleaderboard.Leaderboard.forEach(element => {
          if (element.PlayFabId == currentPlayerId)
           {
             CurrentScore = element.Profile.DisplayName + " : " + element.entry.StatValue.toString();
             return;
           }
        });
    }
    else
        CurrentScore = "Something went wrong. Could not get leaderboard highscore.";

How can I get the player's score?

0 Likes 0 ·
Show more comments
Show more comments

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.