question

Dan Mlodecki avatar image
Dan Mlodecki asked

Looking up group membership information in Azure Function

I'm a bit stuck here in the Groups Azure Function PlayFab API.

I have a valid user calling the Azure Function, and I have their context data including their TitlePlayerAccountID.

I'm trying to check if the user is a member of group "admin" and thus allow updating of game metadata in the underlying database.

This code does not work:

var gr = new GetGroupRequest();
gr.GroupName = "admin";
var group = await PlayFab.PlayFabGroupsAPI.GetGroupAsync(gr);
var output = $"group is {group}\n";
output += $"group id is {group.Result.Group}\n";

This is borked too:

var group = PlayFab.PlayFabGroupsAPI.GetGroupAsync(new GetGroupRequest() {GroupName = "admin"});
output += $"group is {group}\n";

I tried executing this query directly to the underlying Http API call with postman, but I couldn't figure out where to stick the EntityToken in the headers, so I just got the "This API method does not allow anonymous callers." result.

I considered capturing the TitlePlayerAccountId and tracking groups in my non-playfab database, but that seems ugly.

Help a fella out? Am I on the right track here or missing something?

Cheers.

Player Data
7 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.

Dan Mlodecki avatar image Dan Mlodecki commented ·

For clarity: After I retrieve the group, I'll check the user against it using the IsMember() method.

0 Likes 0 ·
Dan Mlodecki avatar image Dan Mlodecki commented ·

Following these instructions got me going with postman, although I have not been able to use it to look up a group by name.

Is the intention that we should be hard-coding group IDs into our code? I would prefer not to do that as it would make using a testing vs. production enviroment more complex.

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

Thank you for the feedback. I will dig into it and try to reproduce the issue. Your patience is appreciated.

0 Likes 0 ·
Dan Mlodecki avatar image Dan Mlodecki commented ·

postman -> groups -> GetGroup

set request body to

{
  "GroupName": "admin"
}

result

{
    "code": 200,
    "status": "OK",
    "data": {
        "GroupName": "admin",
        "Group": {
            "Id": "7FF0xxxxxxxxxxABF8",
            "Type": "group",
            "TypeString": "group"
        },
        "MemberRoleId": "members",
        "AdminRoleId": "admins",
        "Roles": {
            "admins": "Administrators",
            "members": "Members"
        },
        "Created": "2020-03-05T07:41:41.555Z",
        "ProfileVersion": 0
    }
}

so good news you can indeed look up a group id by name.

Now in the Azure Function monitor I see:

Must call Client Login or GetEntityToken before calling this method

But did I not call client login when I called this Azure Function through the PlayFab api?

Will continue to test.

0 Likes 0 ·
Dan Mlodecki avatar image Dan Mlodecki commented ·

A little further... Added a call to GetEntityTokenAsync():

PlayFabSettings.staticSettings.TitleId = "<my playfab title id>";
PlayFabSettings.staticSettings.DeveloperSecretKey = "Q_top_secret_secret_key_P";
var titleResponse = await PlayFabAuthenticationAPI.GetEntityTokenAsync(new GetEntityTokenRequest());
var title = titleResponse.Result.Entity;
var output = $"Title is {title}\n";

which allows GetGroupAsync() to run:

var groupResponse = await PlayFab.PlayFabGroupsAPI.GetGroupAsync(new GetGroupRequest() {GroupName = "admin"});
var group = groupResponse.Result.Group;
var output = $"group is {group}\n"
0 Likes 0 ·
Show more comments

1 Answer

·
JayZuo avatar image
JayZuo answered

The problem here is in your code, in this line

var isMemberResponse = PlayFabGroupsAPI.IsMemberAsync(new IsMemberRequest() {Entity = {Id = userToCheck.Id, Type = userToCheck.Type}, Group = group});

You should use

 var isMemberResponse = await PlayFabGroupsAPI.IsMemberAsync(new IsMemberRequest() { Entity = new PlayFab.GroupsModels.EntityKey { Id = userToCheck.Id, Type = userToCheck.Type }, Group = group });

You've missed "await" and "new EntityKey" in your code.After this, your code should be able to work.

Besides, since Entity API only needs entity token to perform authentication and we can always get TitleAuthenticationContext from CloudScript context, we can also use InstanceAPI here to reduce the call of "GetEntityTokenAsync" like the following:

PlayFabSettings.staticSettings.TitleId = context.TitleAuthenticationContext.Id;
var titleContext = new PlayFabAuthenticationContext
{
    EntityId = context.TitleAuthenticationContext.Id,
    EntityToken = context.TitleAuthenticationContext.EntityToken
};
var groupAPI = new PlayFabGroupsInstanceAPI(titleContext);
var groupResponse = await groupAPI.GetGroupAsync(new PlayFab.GroupsModels.GetGroupRequest() { GroupName = args.GroupName });
var group = groupResponse.Result.Group;
log.LogInformation($"group is {group.Id}");
// Check if the calling user is a member of group admin
var userToCheck = context.CallerEntityProfile.Entity;
// Have to convert the user entity because "Cannot convert source type 'PlayFab.ProfilesModels.EntityKey' to target type 'PlayFab.GroupsModels.EntityKey'"
var isMemberResponse = await groupAPI.IsMemberAsync(new IsMemberRequest() { Entity = new PlayFab.GroupsModels.EntityKey { Id = userToCheck.Id, Type = userToCheck.Type }, Group = group });
log.LogInformation($"IsMember is {isMemberResponse.Result.IsMember}");
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.

Dan Mlodecki avatar image Dan Mlodecki commented ·

A very tidy section of code. Thank you!

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.