question

Pat avatar image
Pat asked

Progressive Rewards Help

My next issue I am having trying to implement the Progressive Reward System is when the CheckIn function gets called I get the the tracker but when trying to get the NextEligibleGrant from it it comes up with NaN. I did a few logs to see what is causing the issue and this one "log.info("TrackerInfo: " + tracker + "\nNext Grant: " + parseInt(tracker[TRACKER_NEXT_GRANT]));" comes up with "TrackerInfo: {"LoginStreak":1,"NextEligibleGrant":1486105627537} Tracker: NaN" Any idea what is happening?

1 comment
10 |1200

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

Bhavesh avatar image Bhavesh commented ·

I found solution, Please check this code.

tracker = JSON.parse(tracker); // You need to add this line before check date and time

log.info("Time Now " + Date.now() + "TrackerInfo: " + tracker + " Tracker: " + parseInt(tracker[TRACKER_NEXT_GRANT]));

if(Date.now() > parseInt(tracker[TRACKER_NEXT_GRANT]))

{

0 Likes 0 ·
brendan avatar image
brendan answered

That doesn't really make sense. The output you're seeing shows the log.info (TrackerInfo and Next Grant), but the "Tracker: " bit after that isn't part of that log statement. Are you logging any other info anywhere else?

10 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.

Pat avatar image Pat commented ·

Oh sorry. The Next Grant was the tracker. I copied an old debug statement. The issue is still the same though.

0 Likes 0 ·
brendan avatar image brendan Pat commented ·

Sorry, to be clear, your log.info statement shows that there should be a "TrackerInfo:" followed by some data, then a "Next Grant" followed by some data. The output has some info after TrackerInfo, then a "Tracker" statement, but no "Next Grant", so I'm having trouble sorting out what it is that we're seeing. Do you have a repro for this you could send us?

0 Likes 0 ·
Pat avatar image Pat commented ·

cloudscript.txt here is the cloudscript that I am running.

0 Likes 0 ·
cloudscript.txt (4.9 KiB)
brendan avatar image brendan Pat commented ·

We are in the process of rebuilding and validating our Cloud Script examples in TypeScript in order to clean things like this up. The issue is that tracker should be set to a JSON object containing the information being tracked. And on any attempt other than the first one for a player, it should work fine, as the code uses JSON.parse to read it from the Value for CheckInTracker (from User Read Only Data). The issue is that in the case of a first-time check, ResetTracker is incorrectly setting tracker to a string. We'll have that cleaned up soon, but in the meantime if you either return an object as intended or simply parse the string that is being returned, that should get this working for you.

0 Likes 0 ·
Pat avatar image Pat commented ·

Okay, I finally got the cloudscript to work. But now I get an error in the c# script when trying to get the item that was granted. this is the line that it errors out on

"List<ItemInstance> grantedItems = PlayFab.Json.JsonWrapper.DeserializeObject<List<ItemInstance>>(result.FunctionResult.ToString());"

and it gives me:

"InvalidCastException: Value is not a convertible object: System.String to System.Collections.Generic.List`1[[PlayFab.ClientModels.ItemInstance, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]"

for the error

0 Likes 0 ·
brendan avatar image brendan Pat commented ·

Can you put a breakpoint into your code to check what the specifics are of the FunctionResult returned, and post that here?

0 Likes 0 ·
Pat avatar image Pat commented ·

I put a debug.log statement for the result.FunctionResult.ToString() and got:

"[{\"PlayFabId\":\"F149D1E4312F4D4E\",\"Result\":true,\"ItemId\":\"Day2\",\"ItemInstanceId\":\"38CDBDA9494A5307\",\"ItemClass\":\"Reward\",\"PurchaseDate\":\"2017-02-03T09:09:40.285Z\",\"Annotation\":\"Granted for logging in over 2 consecutive days.\",\"CatalogVersion\":\"Store\",\"DisplayName\":\"Coins 200\",\"UnitPrice\":0,\"BundleContents\":[]}]"

0 Likes 0 ·
brendan avatar image brendan Pat commented ·

Okay, so you're returning an array of GrantedItemInstance, so that's what you'll want to deserialize the response to (a list of GrantedItemInstance, that is). Again, we'll be updating the sample scripts shortly to account for these issues - if you'd prefer, you could hold off on working with these until we've had a chance to update them.

0 Likes 0 ·
Pat avatar image Pat commented ·

yeah I think I'm just going to wait. Could you send me message when they have been updated?

0 Likes 0 ·
brendan avatar image brendan Pat commented ·

Yes, we'll post here when they've been updated.

0 Likes 0 ·
Bhavesh avatar image
Bhavesh answered

Hello sir, I am getting this error

"Level": "Info",

CloudScript:

log.info("TrackerInfo: " + tracker + " Tracker: " + parseInt(tracker[TRACKER_NEXT_GRANT])); 



Response:         
"Message": "TrackerInfo: {\"LoginStreak\":1,\"NextEligibleGrant\":1582314383681} Tracker: NaN", "Data": null
10 |1200

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

renatobarbosapimpereira avatar image
renatobarbosapimpereira answered
handlers.CheckIn = function(args) {


	var GetUserReadOnlyDataRequest = {
        "PlayFabId": currentPlayerId,
        "Keys": [ CHECK_IN_TRACKER ]
    }; 
    var GetUserReadOnlyDataResponse = server.GetUserReadOnlyData(GetUserReadOnlyDataRequest);
    
    // need to ensure that our data field exists
    var tracker = {}; // this would be the first login ever (across any title), so we have to make sure our record exists.
    if(GetUserReadOnlyDataResponse.Data.hasOwnProperty(CHECK_IN_TRACKER))
    {
    	tracker = JSON.parse(GetUserReadOnlyDataResponse.Data[CHECK_IN_TRACKER].Value);
    	var nextGrant = JSON.parse(tracker);
    //	var d = JSON.parse(tracker);
    //	var e = d[TRACKER_NEXT_GRANT];
    }
    else
    {
    	tracker = ResetTracker();
  		
  		// write back updated data to PlayFab
  		UpdateTrackerData(tracker);


  		log.info("This was your first login, Login tomorrow to get a bonus!");
  		return JSON.stringify([]);
    }
	


	if(Date.now() > parseInt(nextGrant[TRACKER_NEXT_GRANT]))
	{	
		// Eligible for an item grant.
		//check to ensure that it has been less than 24 hours since the last grant window opened
		var timeWindow = new Date(parseInt(tracker[TRACKER_NEXT_GRANT]));
		timeWindow.setDate(timeWindow.getDate() + 1); // add 1 day 


		if(Date.now() > timeWindow.getTime())
		{
			// streak ended :(			
			tracker = ResetTracker();
			UpdateTrackerData(tracker);


			log.info("Your consecutive login streak has been broken. Login tomorrow to get a bonus!");
			return JSON.stringify([]);
		}


		// streak continues
		nextGrant[TRACKER_LOGIN_STREAK] += 1;
		var dateObj = new Date(Date.now());
		dateObj.setDate(dateObj.getDate() + 1); // add one day 
		nextGrant[TRACKER_NEXT_GRANT] = dateObj.getTime();


		// write back updated data to PlayFab
		log.info("Your consecutive login streak increased to: " + nextGrant[TRACKER_LOGIN_STREAK]);
		UpdateTrackerData(JSON.stringify(nextGrant));


		// Get this title's reward table so we know what items to grant. 
		var GetTitleDataRequest = {
	    	"Keys": [ PROGRESSIVE_REWARD_TABLE ]
	    }; 
	    var GetTitleDataResult = server.GetTitleData(GetTitleDataRequest);
	    
	    // ---
	    if(!GetTitleDataResult.Data.hasOwnProperty(PROGRESSIVE_REWARD_TABLE))
	    {
	    	log.error("Rewards table could not be found. No rewards will be given. Exiting...");
	        return JSON.stringify([]);
	    }
	    else
	    {
	    	// parse our reward table
	    	var rewardTable = JSON.parse(GetTitleDataResult.Data[PROGRESSIVE_REWARD_TABLE]);
	    	
	    	// find a matching reward 
	    	var reward;
	    	for(var level in rewardTable)
	    	{
	    		if( nextGrant[TRACKER_LOGIN_STREAK] >= rewardTable[level][PROGRESSIVE_MIN_CREDITS])
	    		{
	    			reward = rewardTable[level][PROGRESSIVE_REWARD];
	    		}
	    	}


	    	// make grants and pass info back to the client.
			var grantedItems = [];
	    	if(reward)
			{
				grantedItems = GrantItems2(reward, nextGrant[TRACKER_LOGIN_STREAK]);
			}
			return grantedItems;
	    }
	}


	return JSON.stringify([]);
};




function ResetTracker()
{
	var reset = {};


	reset[TRACKER_LOGIN_STREAK] = 1;
	
	var dateObj = new Date(Date.now());
	dateObj.setDate(dateObj.getDate() + 1); // add one day 


	reset[TRACKER_NEXT_GRANT] = dateObj.getTime();
	return JSON.stringify(reset);
}




function UpdateTrackerData(data)
{
    var UpdateUserReadOnlyDataRequest = {
        "PlayFabId": currentPlayerId,
        "Data": {}
    };
    UpdateUserReadOnlyDataRequest.Data[CHECK_IN_TRACKER] = JSON.stringify(data);


    server.UpdateUserReadOnlyData(UpdateUserReadOnlyDataRequest);
}


function UpdateTrackerData2(data)
{
    var UpdateUserReadOnlyDataRequest = {
        "PlayFabId": currentPlayerId,
        "Data": {}
    };
    UpdateUserReadOnlyDataRequest.Data[CHECK_IN_TRACKER] = data;


    server.UpdateUserReadOnlyData(UpdateUserReadOnlyDataRequest);
}


function GrantItems2(items, count)
{
	log.info("Granting: " + items);
    var parsed = Array.isArray(items) ? items : [ items ];


    var GrantItemsToUserRequest = {
        "PlayFabId" : currentPlayerId,
        "ItemIds" : parsed,
        "Annotation" : "Granted for logging in over " + count + " consecutive days.",
        "CatalogVersion" : "1"
    };


    var GrantItemsToUserResult = server.GrantItemsToUser(GrantItemsToUserRequest);
    return JSON.stringify(GrantItemsToUserResult.ItemGrantResults);


}
10 |1200

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

renatobarbosapimpereira avatar image
renatobarbosapimpereira answered

This is the script fixed and working

10 |1200

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

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.