question

Collin Patrick avatar image
Collin Patrick asked

Is there any up to date PlayFab Azure Functions documentation

As the title suggests, I can't find any documentation or resources that agree with each other. The Azure documentation does not match the PlayFab documentation which does not match what I had to do to make things "work".

PlayFabDocs:

 namespace PlayFabCS2AFSample.HelloWorld
 {
     public static class HelloWorld
     {
         [FunctionName("HelloWorld")]
         public static async Task<dynamic> Run(
             [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
             ILogger log)
         {
             FunctionExecutionContext<dynamic> context = JsonConvert.DeserializeObject<FunctionExecutionContext<dynamic>>(await req.ReadAsStringAsync());
    
             dynamic args = context.FunctionArgument;
    
             var message = $"Hello {context.CallerEntityProfile.Lineage.MasterPlayerAccountId}!";
             log.LogInformation(message);
    
             dynamic inputValue = null;
             if (args != null && args["inputValue"] != null)
             {
                 inputValue = args["inputValue"];
             }
    
             log.LogDebug($"HelloWorld: {new { input = inputValue} }");
    
             // The profile of the entity specified in the 'ExecuteEntityCloudScript' request.
             // Defaults to the authenticated entity in the X-EntityToken header.
             var entityProfile = context.CallerEntityProfile;
    
             var api = new PlayFabDataInstanceAPI(
                 new PlayFabApiSettings
                 {
                     TitleId = context.TitleAuthenticationContext.Id
                 },
                 new PlayFabAuthenticationContext
                 {
                     EntityToken = context.TitleAuthenticationContext.EntityToken
                 }
             );
    
             var apiResult = await api.SetObjectsAsync(
                 new SetObjectsRequest
                 {
                     Entity = new EntityKey
                     {
                         Id = entityProfile.Entity.Id,
                         Type = entityProfile.Entity.Type
                     },
                     Objects = new List<SetObject> {
                     new SetObject
                     {
                         ObjectName =  "obj1",
                         DataObject = new
                         {
                             foo = "some server computed value",
                             prop1 = "bar"
                         }
                     }
                 }
                 });
    
             return new { messageValue = message };
         }
     }
 }

What works on my end:

 public class HelloWorld
     {
         private readonly ILogger<HelloWorld> _logger;
    
         public HelloWorld(ILogger<HelloWorld> logger)
         {
             _logger = logger;
         }
    
         [Function("HelloWorld")]
         public async Task<dynamic> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest aReq)
         {
             //string name = aReq.Query["name"];
    
             string requestBody = await new StreamReader(aReq.Body).ReadToEndAsync();
             FunctionExecutionContext<dynamic> context = JsonConvert.DeserializeObject<FunctionExecutionContext<dynamic>>(requestBody);
    
             dynamic args = context.FunctionArgument;
    
             var message = $"Hello {context.CallerEntityProfile.Lineage.MasterPlayerAccountId}!";
             _logger.LogInformation(message);
    
             dynamic inputValue = null;
             if (args != null && args["inputValue"] != null)
             {
                 inputValue = args["inputValue"];
             }
    
             _logger.LogDebug($"HelloWorld: {new { input = inputValue }}");
    
             // The profile of the entity specified in the 'ExecuteEntityCloudScript' request.
             // Defaults to the authenticated entity in the X-EntityToken header.
             var entityProfile = context.CallerEntityProfile;
    
             var api = new PlayFabDataInstanceAPI(
                 new PlayFabApiSettings
                 {
                     TitleId = context.TitleAuthenticationContext.Id
                 },
                 new PlayFabAuthenticationContext
                 {
                     EntityToken = context.TitleAuthenticationContext.EntityToken
                 }
             );
    
             var apiResult = await api.SetObjectsAsync(
                 new SetObjectsRequest
                 {
                     Entity = new PlayFab.DataModels.EntityKey
                     {
                         Id = entityProfile.Entity.Id,
                         Type = entityProfile.Entity.Type
                     },
                     Objects = new List<SetObject> {
                     new SetObject
                     {
                         ObjectName =  "obj1",
                         DataObject = new
                         {
                             foo = "some server computed value",
                             prop1 = "bar"
                         }
                     }
                 }
                 });
    
             return new OkObjectResult(new { messageValue = message });
         }
     }

Right now I am trying to get the function calls to work locally for testing purposes using this documentation (https://learn.microsoft.com/en-us/gaming/playfab/features/automation/cloudscript-af/local-debugging-for-cloudscript-using-azure-functions) Again, the code provided is outdated and did not compile out of the box, but I did manage to get the LocalExecuteFunction class to compile by making similar changes like the HelloWorld function, but when I call the functions from Unity, I get this error because the download handler data byte array is null.

 : Unhandled error in PlayFabUnityHttp: System.NullReferenceException: Object reference not set to an instance of an object
   at PlayFab.Internal.PlayFabUnityHttp+<Post>d__12.MoveNext () [0x001ba] in F:\Unity Projects\Deck Builder\Deck Builder\Assets\PlayFabSDK\Shared\Internal\PlayFabHttp\PlayFabUnityHttp.cs:188 
 UnityEngine.Debug:LogError (object)

When I change the method to return the OkObjectResult from AspNet (I don't even know if using it is correct) like in my other updates, the data is no longer null, but the resulting object is.

                     return new OkObjectResult(new
                     {
                         code = 200,
                         status = "OK",
                         data = functionResult
                     });

I'm not very familiar with the HTTP side of C#, but man is this documentation making things way harder than it should be. I just can not seem to figure this out.

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

·
Xiao Zha avatar image
Xiao Zha answered

Sorry for the inconvenient. And currently, the code provided in PlayFab Azure function docs are suitable for Azure Functions V4 and .NET 6. If you want to use higher version like .Net 8 or using .Net 6 isolated, you could post a feature request for it.

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.