question

kevinwinegardner avatar image
kevinwinegardner asked

Trying to make a Content Creation Utility - ExecuteCloudScript to call SetTitleData

My CloudScript function is below.

handlers.setTitleDataCloudScript = function (args, context) {
    var collectionName = args.collection;
    var itemKey = args.itemKey;
    var itemValue = args.itemValue;


    log.debug("setTitleDataCloudScript: args=", JSON.stringify(args));
    log.debug("setTitleDataCloudScript: context=", JSON.stringify(context));
    //get title data
    var getTitleDataRequest = { "Keys": [collectionName] };
    var getTitleDataResponse = server.GetTitleData(getTitleDataRequest);
    if (!getTitleDataResponse.Data.hasOwnProperty(collectionName)) {
        log.error("Collection not found in TitleData. Exiting...");
        return JSON.stringify([]);
    }
    else {
        log.debug("setTitleDataCloudScript: getTitleDataResponse=", JSON.stringify(getTitleDataResponse));
        var collection = getTitleDataResponse.Data.collection;
        log.debug("setTitleDataCloudScript: collection=", JSON.stringify(collection));


        collection[itemKey] = itemValue;
        if (!collection.hasOwnProperty(itemKey)) {
            log.error("Item could not found in Collection. Exiting...");
            return JSON.stringify([]);
        }
        else {
            var setTitleDataRequest = {
                "Key": collectionName,
                "Value": collection
            };
            var setTitleDataResponse = server.SetTitleData(setTitleDataRequest);
            return itemValue;
        }
    }
};

The hope with this function is that when passed something like args="{\"collection\":\"Products\",\"itemKey\":\"Mountain Dew\",\"itemValue\":{\"Line\":\"grocery\",\"category\":\"soda\"}}" that it will find the Products object in my project's TitleData and add to it the item Mountain Dew (or update Mountain Dew if it is already present. However, the line

collection[itemKey] = itemValue;

always fails with the error

"StackTrace": "TypeError: Cannot set property 'Mountain Dew' of undefined\n    at handlers.setTitleDataCloudScript (C3CB-main.js:421:29)"

Since it doesn't seem like the JS for CloudScripts includes the Object.assign() function, I know of no other way to add another item to the object collection looked up - "Products" in this case.

Please note, I have altered the object data for this publicly posted question. The data in our actual C3CB project is different.

Any assistance you can offer on this would be greatly appreciated.

Thanks.

CloudScriptTitle Data
10 |1200

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

Citrus Yan avatar image
Citrus Yan answered

Hi Kevin,

I took a look at your project and I think I understand what you are trying to achieve. It’s cumbersome and error-prone to do it by handling with title data directly, unfortunately, I didn’t manage to fix this issue. However, considering your situation, it’s better not to use Get/SetTitleData to create or update content, the reasons are the following:

a)It’s cumbersome and error-prone

b)Title data are not meant to updated frequently, it is best suited for "global constant/static data", and is not suitable or reliable as "global variables".

Therefore, I suggest you take advantage of PlayFab’s Entity Programming Model, with this, you can directly add or update content to your title entity using SetObjects API. This API sets JSON objects on the requested entity profile(for you situation, it’s title entity profile). You can use the version number to perform optimistic concurrency operations during the update. If the current version differs from the version in the request the request will be ignored. If no version is set on the request then the value will always be updated if the values differ. I think it’s easier for you to implement the functionality with the entity system, you can try it to see if it works.

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

kevinwinegardner avatar image kevinwinegardner commented ·

Hey Citrus.

Thank you for having another look at this. The utility we are trying to make with using SetTitleData would be just for our game designers/content creators. Our hope is to remove the need for engineering involvement in their content creation process, and having to modify JSON directly in a web form is not such a thing some of them would be comfortable with (not to mention the access to PlayFab, which we keep limited). So, the SetTitleData usage is merely to bridge the gap between their documentation and our game.

I'll have a look at the SetObjects API to see how we can make use of this. Although, given our architecture, I would have to get others from our company to actually implement the API calls. I'm curious if you know if/when the SetObjects API will be in an SDK for Unity.

Thanks.

0 Likes 0 ·
Citrus Yan avatar image Citrus Yan kevinwinegardner commented ·

Hi Kevin, SetObjects API is in Unity SDK right now, I tested in my project. You can navigate to this tutorial to have a try:)

0 Likes 0 ·
kevinwinegardner avatar image kevinwinegardner commented ·

I believe I had some bad JS code in there - in particular the ".collection" was not actually an object in the response object. I believe the code errors have been fixed now, though, in the latest version of our CloudScripts. However, even after I get a successful CloudScript execution, I still don't see any new data show up in our project in the Content section in PlayFab. Maybe I could use a simple CloudScript example that DOES actually properly create a new item of content and another example that updates an existing item of content.

0 Likes 0 ·
Citrus Yan avatar image Citrus Yan kevinwinegardner commented ·

OK, let's see if that works for you, I will keep this thread updated.

0 Likes 0 ·
kevinwinegardner avatar image kevinwinegardner Citrus Yan commented ·

Maybe I wasn't clear - it still does *NOT* work.
I know I had and fixed some JS code errors, and now the script executes the call to `server.SetTitleData(setTitleDataRequest);`. Furthermore, I believe the value of setTitleDataRequest is what I desire it to be. However, this still results in no changes made to my project's Content - Title Data

0 Likes 0 ·
Show more comments
Show more comments
Citrus Yan avatar image
Citrus Yan answered

Hi Kevin, I tried to reproduce your issue but my test worked fine. I used Postman to Execute the function setTitleDataCloudScript. Here is my request info:

{
  "PlayFabId" : "29EBD5013B37FEE2",
  "FunctionName": "setTitleDataCloudScript",
  "FunctionParameter": {
            "collection":"Products","itemKey":"Mountain Dew","itemValue":{"Line":"grocery","category":"soda"}
  },
  "RevisionSelection": "Live",
  "GeneratePlayStreamEvent": true
}

This is the response I got:

{
    "code": 200,
    "status": "OK",
    "data": {
        "FunctionName": "setTitleDataCloudScript",
        "Revision": 59,
        "FunctionResult": "[]",
        "Logs": [
            {
                "Level": "Debug",
                "Message": "setTitleDataCloudScript: args=",
                "Data": "{\"collection\":\"Products\",\"itemKey\":\"Mountain Dew\",\"itemValue\":{\"Line\":\"grocery\",\"category\":\"soda\"}}"
            },
            {
                "Level": "Debug",
                "Message": "setTitleDataCloudScript: context=",
                "Data": "{\"playerProfile\":null,\"playStreamEvent\":null,\"triggeredByTask\":null}"
            },
            {
                "Level": "Error",
                "Message": "Collection not found in TitleData. Exiting..."
            }
        ],
        "ExecutionTimeSeconds": 0.0230322,
        "ProcessorTimeSeconds": 0.0,
        "MemoryConsumedBytes": 41232,
        "APIRequestsIssued": 1,
        "HttpRequestsIssued": 0
    }
}

During the test, I found that there were some problems with the args string you provided, maybe that’s the case why you got this error. You can double-check the argument you passed to the function to see if there are any errors. For example, try this:

"\{\"collection\":\"Products\",\"itemKey\":\"Mountain Dew\",\"itemValue\":{\"Line\":\"grocery\",\"category\":\"soda\"}\}"
10 |1200

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

kevinwinegardner avatar image
kevinwinegardner answered

Hey Citrus, thanks for your response. I do also get the Collection not found issue if, in fact, I have not added the collection as a base object in my project's Content section. However, once you get past that point by adding the Collection name - this is where it is not working for me, and I'm unable to add any items to that collection. If you're able to look at my project (C3CB), it may be easier to look into whats going wrong.

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.

Citrus Yan avatar image Citrus Yan commented ·

I will get to this and keep you informed of any progress:)

0 Likes 0 ·

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.