New Google Auth returns incorrect Google ID

I’ve configured my 3.16.0 server with the credentials_json for the updated Google auth process for Google Play Games 0.11.x and also updated my Unity project to match.

Now when a user authenticates with AuthenticateGoogleAsync, passing the new server side token, it creates a new user account with a different (incorrect) Google ID to their existing account. The Google ID returned from GooglePlayGames.Authenticate is their correct ID but the ID that Nakama derives from the token is different and is formatted with a letter prefix.

For example, my Google ID is 111178834567830394331 and the new account has the ID g09515347187652732951.

Is this a bug, or am I doing something wrong? I know this is a new feature and the documentation is still a bit patchy. Thanks.

Further digging reveals that the Nakama logs contain the following debug

Obtained the player profile using an access token.","token":{"access_token":"ya29....

and feeding this token into:

https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=ya29....

shows that the token has appdata and game_lite scopes, but not games

{
  "azp": "...",
  "aud": "...",
  "scope": "https://www.googleapis.com/auth/drive.appdata https://www.googleapis.com/auth/games_lite",
  "exp": "1684333602",
  "expires_in": "2269",
  "access_type": "offline"
}

However, the APIs console confirm that my app DOES have games scope. Can anyone shed any light on this please?

@flavio perhaps you have more context on this, can you help?

1 Like

I’ve just noticed in the debug that Google is sending the ID over:

"player":{"playerId":"g09515347186352732951","displayName":"DaveOak","avatarImageUrl":"https://lh3.googleusercontent.com/BDYz2mEEqtB9JGCH_uR0rE6lIIJOnoRhAzdla91I-sFg-cdl1NUi79AYciv5iujzL7711Q"}

Probably not a Nakama issue then. I’m suspecting something to do with Google’s “Next Generation Player ID” which is an app scoped player ID similar to that used by Facebook. However, existing players are supposed to retain their previous ID for the game. Besides, I haven’t enabled next gen IDs for my game yet. All very strange,

The call in Nakama to retrieve the player data is returning data for the game Puzzle Master, which is not my game! I’ve checked the config in config.yml and my setup in Unity and Google Play and can find no errors.

I have checked the GooglePlayGames instance and it is definitely my game that I am authenticating with in the client, and the ID token from RequestServerSideAccess is being passed into Nakama.AuthenticateGoogleAsync. Something is seemingly going wrong on the server side.

https://www.googleapis.com/games/v1/players/me?access_token=ya29...
{
  "kind": "games#player",
  "playerId": "g09515347186352732951",
  "displayName": "DaveOak",
  "avatarImageUrl": "https://lh3.googleusercontent.com/BDYz2mEEqtB9JGCH_uR0rE6lIIJOnoRhAzdla91I-sFg-cdl1NUi79AYciv5iujzL7711Q",
  "bannerUrlPortrait": "https://lh3.googleusercontent.com/gE_v155mLX2ILyavanqoE8z2JwsdafesUOVYOaCU7dtNA_cC9_2AG9dKmnDCE2WGYkgOtteOKU7OF1mOdjM",
  "bannerUrlLandscape": "https://lh3.googleusercontent.com/c3KnWJAm-dCkmS4Yv5qZvwj15hH-yvuMPZTrdwwIcStIeWuXhyvo-_3Z0Xe_veDwSKSdg1fCvMBmJo1d6Q",
  "originalPlayerId": "111178832015830394331",
  "profileSettings": {
    "kind": "games#profileSettings",
    "profileVisible": true,
    "friendsListVisibility": "VISIBLE"
  },
  "experienceInfo": {
    "kind": "games#playerExperienceInfo",
    "currentExperiencePoints": "664000",
    "lastLevelUpTimestampMillis": "1650188546879",
    "currentLevel": {
      "kind": "games#playerLevel",
      "level": 25,
      "minExperiencePoints": "650000",
      "maxExperiencePoints": "700000"
    },
    "nextLevel": {
      "kind": "games#playerLevel",
      "level": 26,
      "minExperiencePoints": "700000",
      "maxExperiencePoints": "750000"
    }
  },
  "title": "Puzzle Master"
}

Hello @DaveOak,

Could you check the configuration of the client credentials for your game? Specifically, that those credentials aren’t shared but specific to your game.

Hi @flavio,

Thanks for getting back. I’ve checked the config to make sure the credentials belong to my game, I’ve created new credentials on the app and tried those with the same result. I’ve also used a Google Admin account to look up my Client ID and it returns the name of my app correctly.

Client ID: 989306798746-f72rec8upeppl51h28bvpkd2jbge90gs.apps.googleusercontent.com
App name: Odd Socks

My next step is to create a minimal server to replicate the authorisation with Google to give me more transparency on the problem.

@flavio

I think I have an answer, and I think it requires a small change to Nakama for all games that currently use legacy player IDs.

The documentation on this is very scant, but it seems that Google is moving everyone to “Next Generation Player IDs” even if they are an existing user. These IDs are application specific so you will get a different ID for each game you play.

In order for game servers to manage this change in IDs, they are providing the old ID along with the new ID so you can remap the IDs in the database. For example, the call to players/me above returns:

  ...
  "playerId": "g09515347186352732951",
  "originalPlayerId": "1111************94331",
   ...

The originalPlayerId field is only present if the player has previously connected to the game with a legacy ID.

I have tested this against another legacy game and against a freshly created game to confirm this behaviour.

I can be involved in the update if required and can certainly run further tests if it helps.

See originalPlayerId in the docs:

As an aside, “Puzzle Master” is not the name of a game but the default rank assigned by Google Play Games. As I don’t use this feature, the default remained unchanged.

I’ve raised an issue in Github to flag this up.

Amazing work figuring this out, @DaveOak. Thank you.

Now, I wonder if it is safe to assume that we should always return the originalPlayerId if present. I don’t truly understand the implications of this part This is only populated for calls ...and only to clients that support remapping player IDs. Would the server need to be aware of this id mapping support in the client?

I assume that, eventually, studios need to migrate the Ids, wouldn’t it be better to it as soon as possible rather than later? I imagine that it’s an unavoidable transition.

1 Like

As Google are doing this as a privacy measure, I think they will eventually phase out the originalPlayerId, so remapping as soon as you get the new ID is probably the way to go.

Rereading your post, I think the remapping takes place purely in the server and the client need never be aware of the Google ID(s).

The client gets and passes on a short lived IdToken from Google login, which the server translates to the ID(s) using Google APIs in order to find the player record. It need never be returned to the client which only really needs the Nakama player ID.

I think the approach is for the server to get the player record from Google and if it contains an originalPlayerId, look for a matching record in the database and if found change the ID to the (new) playerId.

Thanks for the kudos by the way :slight_smile:

From the docs:

originalPlayerId : The player ID that was used for this player the first time they signed into the game in question. This is only populated for calls to player.get for the requesting player, only if the player ID has subsequently changed, and only to clients that support remapping player IDs.

In this context, I think a game server is a client of the Google APIs.
How the API knows whether or not you support remapping is a mystery! In my tests this field was returned so long as it had previously been used (i.e. pre-existing game accounts).