Get Player's unique Google Play ID

Quick question due to the current lack of OnlineSubsystem documentation. How - if possible - would I get the player’s unique Google Play ID from the subsystem or otherwise, or some other player specific unique identification. I’ve looked through the source of various OnlineSubsystemGooglePlay files but haven’t yet found anything promising. Some thing’s I’ve tried include:

  • onlineSubsystem->GetIdentityInterface()->GetUniquePlayerId(0).Get().ToString();

  • Returns empty string

  • onlineSubsystem->GetIdentityInterface()->GetPlayerNickname(0);

  • Returns “NONE”. Set in FOnlineIdentityGooglePlay constructor and does not appear to be set to anything else in the rest of the code.

  • PlayerController->PlayerState->PlayerID;

  • Always 256 whether on PC or Android

  • PlayerController->PlayerState->UniqueId.ToString();

  • Returns “INVALID”

  • PlayerController->PlayerState->PlayerName;

  • Returns “INVALID”

  • PlayerController->PlayerState->GetNetDriver()->LowLevelGetNetworkNumber();

  • Crashes. Idea from: How to get player steam id? - C++ - Epic Developer Community Forums

One potential way I thought of would be to work through onlineSubsystem->GetGameServices()->Android Functions but it appears impossible to include OnlineSubsystemGooglePlay.h itself in my files (I have OnlineSubsystemGooglePlay as a dependency on Android builds but the build still fails).

Thanks,

Hi danm36,

See if this thread helps: android - Get a user ID from Google Play Services? - Stack Overflow

Hey,

I’m trying to do something similar, and the Google Play SDK in the third party directories seem to contain exactly what I need, but I can’t seem to include that directly (And that’s probably not the best way to do things). I do notice that OnlineSubsystemGooglePlay provides a method to access these services through GetGameServices() but I cannot find any way to cast the default IOnlineSubsystem pointer to a OnlineSubsystemGooglePlay pointer, mainly due to the include failing. I include:

/Runtime/Online/Android/OnlineSubsystemGooglePlay/Public/OnlineSubsystemGooglePlay.h

and only do so during an Android build, but the include fails when trying to include the various files within OnlineSubsystemGooglePlay.h (A lot of which are in the Private directory) with file not found errors. I have tried various combinations of PublicDependencyModuleNames, PrivateDependencyModuleNames, PublicIncludePaths and PrivateIncludePaths in my build.cs but it still doesn’t appear to recognize these other header files and I cannot complete the cast.

Edit:

Actually I’m not sure if I tried PublicIncludePaths. I’ll give that an attempt when I get home.

Would be nice to have this as a blueprint node :frowning:

1 Like

Alright, tried all the various combinations and more, and have learnt a lot more about the public/private system, the end result seemingly making including OnlineSubsystemGooglePlay.h impossible.

It seems a bit odd - as a result of this system - to have certain Google Play Subsystem headers in the private directory, making it impossible to include OnlineSubsystemGooglePlay.h anywhere but the OnlineSubsystemGooglePlay module. After all, the GetGameServices() method provided by this particular class would be extremely useful. Is there any potential workaround for this that would allow me to access the current user’s data, or will I have grab a copy of the engine source and implement various methods that way? (I might still do this anyway and send a pull request).

Hi danm36,

Unfortunately, I think the only workarounds for this will involve modifying the engine, though you might be able to just move the other Google Play subsystem headers you need from the “Private” directory to the “Public” directory. As you’ve discovered, access to this data hasn’t been hooked up in the Google Play subsystem yet :(. The GetGameServices() function was meant to be used internally by the individual Google Play subsystem interfaces, since they need access to it.

Alright, thanks for the info. I’m currently adding a small bit of code to the subsystem with help from the , and subsystems. It ain’t going to be that pretty, but I’ll probably send a pull request when I get it working (It will only handle the unique ID for now).

Thanks again!

Sorry for the inconvenience. If you’re working on a pull request, I’ll mention that I refactored how login is handled for Google Play in this commit for 4.9. We’ll post more information about this change soon, and it will be documented in the release notes. Just a friendly note that if your PR changes this code, in this case we’ll be more likely to integrate it if it’s based off the master branch! :slight_smile:

Currently working on promoted but I’ll switch to master for this. No worries with regards to the inconvenience, just wanted to make sure there wasn’t a system in place that I missed or would circumvent if I implemented my own system. The way I’ve got it now is a very feeble FUserOnlineAccountGooglePlay class that only implements and stores the unique ID, and a few modifications to FOnlineIdentityGooglePlay to use that class instead of returning nullptr, mainly because my knowledge of the other core details like the user/auth attributes and such is minimal at the moment (Although I hope to build upon this more over time)

I know I mentioned master but the 4.9 branch would work as well and should be more stable. I’m sure the commit I mentioned will make it into the promoted branch too, I’m just not sure when.

Alright, interesting issue has popped up. I’ve moved to master and am correctly showing the login UI (Well, I think I’m correct using a simple call to onlineSubsystem->GetExternalUIInterface()->ShowLoginUI()) but when I try to grab the user data from gpg::PlayerManager::FetchSelfBlocking(), it results in response with ERROR_NOT_AUTHORIZED as the status. Naturally I assumed this was a permissions issue, but no matter what permissions I add, it still reports ERROR_NOT_AUTHORIZED. From logging in via one of my classes, I call onlineSubsystem->GetIdentityInterface()->GetUserAccount() where the following extremely ugly test code resides:



UE_LOG(LogOnline, Warning, TEXT("XYZ GP - Begin get game services."));
gpg::GameServices* gs = MainSubsystem->GetGameServices();

UE_LOG(LogOnline, Warning, TEXT("XYZ GP - Begin fetch self blocking."));
gpg::PlayerManager::FetchSelfResponse playerFetch = gs->Players().FetchSelfBlocking();
UE_LOG(LogOnline, Warning, TEXT("XYZ GP - Response Status %i."), playerFetch.status);

UE_LOG(LogOnline, Warning, TEXT("XYZ GP - Begin get own player data."));
gpg::Player gsplayer = playerFetch.data;
UE_LOG(LogOnline, Warning, TEXT("XYZ GP - Player valid = %s."), gsplayer.Valid() ? TEXT("true") : TEXT("false"));

FString ID = FString(gsplayer.Id().c_str());
UE_LOG(LogOnline, Warning, TEXT("XYZ GP - Got ID %s."), *ID);

return MakeShareable(new FUserOnlineAccountGooglePlay(ID)); //FUserOnlineAccountGooglePlay is essentially a stipped down clone of FUserOnlineAccountAmazon


I fully realise that this code can be shrunk down to two or three lines.

Now, I’m just wondering if you can provide any insight as to why I would get ERROR_NOT_AUTHORIZED for this, or at the very least some hints as to how the system works or where I’m going wrong. Surprisingly, Google searching for this returned very few errors, and the GPG docs don’t help much with regards to permissions or whatnot.

Edit:
Just like to add that I’m running launching this from the editor. My signing keys are correctly set up (Achievements work correctly at least) and my account is a valid tester for the Google Play Services, although I don’t know how launching from editor differs from packaging for shipping in this case. When I’m next available, I’ll package the game properly and test using that.

In addition, I just noticed that the small banner telling you that you’ve signed in no longer appears in this version.

Edit 2: Electric Boogaloo:
Well I’m a dunce. Just looked through LogCat and found in big red text that the Google Play Game Services API is not enabled for my project (I can confirm it is in my Alpha published version, so the settings are correct), which gives me almost 100% confidence that I just need to package the game and I’ll be golden.

Edit 3
Nope, packaging didn’t help (Although I can’t see any Google Play Service errors in LogCat now, so maybe it did something)

Ah, I suspect your .apk is being signed with the debug key in your Android SDK directory - which will be the case if you’re launching from the editor or packaging without the “For distribution” option checked. If so, you’ll need to make sure that the debug signing key fingerprint is registered with another linked app on the Google developer console.

Excellent! Thanks for the help, it works perfectly with the debug key (I completely forgot about that)! Now to just neaten up the code and send a pull request. I’ll even make a get unique ID blueprint node for KillerSneak.

That would be awesome, if you’re able to pull it of it’s also much easier to integrate the Google Play Services Save Game feature(s) (I hope)

Any news / progress on this? This will be very handy for storing progress on a server bound to the users GoogleID(s)

This is still completely impossible in 4.10, and I really do not want to avoid to a source build of the engine to try and work around this.

I need this to be able to have Save-Games on the device that are tied to profiles. Without it there’s no way to do this!

I have made a plugin for getting the user’s unique id, nickname and auth token through blueprints (and c++ of course). This is only valid for google play logins.