So I'm calling an Azure function from my client. The azure function calls ListMultiplayerServersAsync().
I was getting an error function side "Must call Client Login or GetEntityToken before calling this method" even though my client was logged in. Digging through the forums, I tried this
var entityResponse = await PlayFabAuthenticationAPI.GetEntityTokenAsync(new GetEntityTokenRequest());
which seemed to get rid of that error. I would like to know if this is right and if so, why. I'm really not sure what's going on here, especially since I did not use the return value for anything.
I then got the error "You must set your titleId before making an api call" function side. The titleID is set in the unity editor via playfab shared settings.
Even so, I also tried
PlayFabSettings.staticSettings.TitleId = "C8E30"; PlayFabSettings.TitleId = "C8E30";
Just before the function call, but it didn't seem to help. I then put the assignments in the static constructor, and once again got the "Must call Client Login or GetEntityToken before calling this method" error.
The call to the azure function is working, and I get a return when using just test data, but once I try to call ListMultiplayerServersAsync() I start getting the problems. Below is the Azure function code, minus most of the debugging stuff.
[FunctionName("RequestServer")] public static async Task<Dictionary<string, object>> RequestServer([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { FunctionExecutionContext<Dictionary<string, string>> context = JsonConvert.DeserializeObject<FunctionExecutionContext<Dictionary<string, string>>>(await req.ReadAsStringAsync()); Dictionary<string, string> args = context.FunctionArgument; Dictionary<string, object> functionResult = new Dictionary<string, object>(); //only put this line in because of the GetEntityToken error, not sure if it is proper usage var entityResponse = await PlayFabAuthenticationAPI.GetEntityTokenAsync(new GetEntityTokenRequest()); ListMultiplayerServersRequest request = new ListMultiplayerServersRequest { BuildId = args["buildId"], Region = args["region"] }; //starting getting errors when I add this in, testing without it works fine ListMultiplayerServersResponse result = (await PlayFabMultiplayerAPI.ListMultiplayerServersAsync(request)).Result; //foreach(MultiplayerServerSummary server in result.MultiplayerServerSummaries) //{ // string serverInfo = $"ServerID: {server.ServerId} SessionID: {server.SessionId} NumOfPlayers: {server.ConnectedPlayers.Count} Status: {server.State}"; // functionResult.Add(server.ServerId, serverInfo); //} return functionResult; }//end of function
Below is the call from the client, which seems to be fine. I call it right from the playfab OnLoginSuccess() callback.
private void RequestServer() { PlayFabCloudScriptAPI.ExecuteFunction( new ExecuteFunctionRequest() { Entity = new PlayFab.CloudScriptModels.EntityKey() { Id = PlayFabSettings.staticPlayer.EntityId, Type = PlayFabSettings.staticPlayer.EntityType, }, FunctionName = AzureFunctionNames.RequestServer, FunctionParameter = new Dictionary<string, string>() { { "buildId", gameConfiguration.BuildId }, {"region", Enum.GetName(typeof(AzureRegion), AzureRegion.EastUs) } }, GeneratePlayStreamEvent = false }, OnRequestServerResult, OnPlayFabCallbackError); }
I've been at this for a couple days now, I could really use some insight. The Azure function tutorials are pretty light compared to the legacy cloudscript, but they did help some. I'm sure it's something simple, but I'm still pretty new using PlayFab and Azure functions.
Any help would be much appreciated.
Edit: So here is the code that finally worked, I do have some questions still.
1. Mainly, why do we need to call
await PlayFabAuthenticationAPI.GetEntityTokenAsync(new GetEntityTokenRequest());
What is it doing behind the scenes because I'm not even using the return value, just calling the function with no parameters.
2. Is there any reason I shouldn't set the titleId and SecretKey in the class's static constructor so all the azure functions can access them with out assigning them every time?
Here is the actual code
[FunctionName("RequestServer")] public static async Task<Dictionary<string, object>> RequestServer([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { FunctionExecutionContext<Dictionary<string, string>> context = JsonConvert.DeserializeObject<FunctionExecutionContext<Dictionary<string, string>>>(await req.ReadAsStringAsync()); PlayFabSettings.staticSettings.TitleId = context.TitleAuthenticationContext.Id; PlayFabSettings.staticSettings.DeveloperSecretKey = Environment.GetEnvironmentVariable(secretKey, EnvironmentVariableTarget.Process); await PlayFabAuthenticationAPI.GetEntityTokenAsync(new GetEntityTokenRequest()); Dictionary<string, string> args = context.FunctionArgument; Dictionary<string, object> functionResult = new Dictionary<string, object>(); ListMultiplayerServersRequest request = new ListMultiplayerServersRequest { BuildId = args["buildId"], Region = args["region"] }; var result = await PlayFabMultiplayerAPI.ListMultiplayerServersAsync(request); return functionResult; }//end of function