GooglePlay Games Login with PlayFab Fix

I had to do this for a project but since it was such a pain, I thought I would share it here since I couldn’t find anything on the internet. To sum it up, getting an Auth token is broken in UE4 which is required for PlayFab to use the LoginWithGoogle authentication method. I managed to implement a fix (it’s not pretty) and since I did not want to use a source version of UE4 but still wanted to use the OnlineSubsystem stuff, I had to modify the GameActivity template since there is no way to modify the code that is called by the OnlineSubsystem with a UPL.

Open up


UE_4.25\Engine\Build\Android\Java\src\com\epicgames\ue4\GameActivity.java.template

in whatever text editor you prefer and add the following:



// Place these somewhere in the import section
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;


// Place this somewhere with the rest of the variable declaration.
private static final int RC_SIGN_IN = 9001;
private GoogleSignInClient mGoogleSignInClient;





// Place this in the onStart() method, I dropped it right after $${gameActivityAfterMainViewCreatedAdditions}$$ on line 3087
try
{
// This needs to be modified for each project
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
.requestProfile()
.requestServerAuthCode([PLAYFAB OAUTH CODE HERE])
.build();

mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
}
catch (Exception e)
{
Log.debug("GoogleSignIn exception caught: " + e.toString());
}
Log.debug("mGoogleSignInClient is " + ((mGoogleSignInClient == null) ? "disabled" : "valid"));





// Replace everything in AndroidThunkJava_GoogleClientConnect() method, also the reason a UPL cannot be used (around line 4293)
if(mGoogleSignInClient != null)
{
Intent intent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(intent, RC_SIGN_IN);
}






// In the activityResult method on line 4554
if(requestCode == RC_SIGN_IN)
{
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess())
{
try
{
Log.debug("Google Client Connect: Getting account");
GoogleSignInAccount account = result.getSignInAccount();

if(account != null)
{
String mServerAuthCode = account.getServerAuthCode();
if(!mServerAuthCode.equals(""))
{
Log.debug("Google Client Connect succeeded");
nativeGoogleClientConnectCompleted(true, mServerAuthCode);
}
else
{
Log.debug("Google Client Connect succeeded but no access token returned");
nativeGoogleClientConnectCompleted(true, "NOT_ACQUIRED");
}
}

}
catch (Exception e)
{
Log.debug("Google Client Connect failed to get auth token: " + e.getMessage());

nativeGoogleClientConnectCompleted(false, "NOT_ACQUIRED");
}
}
else
{
Log.debug("Google Client Connect result was a failure");
nativeGoogleClientConnectCompleted(false, "NOT_ACQUIRED");
}




2 Likes

i try that example but when i do packaging,
but its stuck with loading and empty page after i choose email to login to
i think the page is about consent screen

Did you replace the


.requestServerAuthCode([PLAYFAB OAUTH CODE HERE])

with the playfab OAuth code? It’s specific to your project once you have setup the connection between GooglePlay and PlayFab

yes i did,
i replace it with ClientId of the credential right?
xxxxxxxxx.apps.googleusercontent.com
that Id right?
and i dont know why, it look like the sign in process is execute 2 times,
1 from the default OSS,
and the 2nd one from the code above

hatebin - mfwvttwqif
thats the template that i write
then
i just call external UI for sign in
Subsystem->GetExternalUIInterface()->ShowLoginUI(_LocalUserNum, false, false, FOnLoginUIClosedDelegate::CreateUObject(this, &ALobbyPC::HandleExternalUIClose));

I used the ShowExternalLoginUI BP for that part not the C++ side so I am not familiar with the gotchas of doing it that way. This was written and tested on 4.24 and 4.25 so if it’s 4.26 you’re using I have not tested it there. I did have an issue where my oauth keys on google’s side got messed up somewhere so I redid all of those and everything worked.

Is there a log file to look at? You can also see an output of UE4 debug logs on the device with


adb logcat -s UE4 -s debug -s DEBUG

At last i make it work,
just some minor problem 1. Why when i show external login ui, it doesnt ask me what account to use, it just automatically login using main account
2. Is it possible the oauth playfab using variable from config instead of hardcoded?

  1. I believe the default behavior is once you have signed in, it will continue to use that account. There are some different behaviors you can use detailed here https://developers.google.com/identi…ndroid/sign-in

  2. Use a UPL per project, this is the section in my Android_UPL.xml file that does this:



<gameActivityOnCreateAdditions>
<insert>
// CUSTOM:
try
{
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
.requestProfile()
.requestServerAuthCode("xxxxxxxxxxxx.apps.googleusercontent.com")
.build();

mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
}
catch (Exception e)
{
Log.debug("GoogleSignIn exception caught: " + e.toString());
}
Log.debug("mGoogleSignInClient is " + ((mGoogleSignInClient == null) ? "disabled" : "valid"));
</insert>
</gameActivityOnCreateAdditions>


then in the Build.cs



if(Target.Platform == UnrealTargetPlatform.Android)
{
DynamicallyLoadedModuleNames.Add("OnlineSubsystemGooglePlay");

var pluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath);
AdditionalPropertiesForReceipt.Add("AndroidPlugin", System.IO.Path.Combine(pluginPath, "Android_UPL.xml"));
}


You will still need to manually add the code to AndroidThunkJava_GoogleClientConnect() but the rest of the code can be done in a UPL file.

Edit:
I attached my UPL for this and X’d the PlayFab auth code, just rename it from txt to xml because I can’t upload XML files for some reason. Just place the UPL in the same folder as the build.cs for your project.

i dont think, this is the cause " I believe the default behavior is once you have signed in, it will continue to use that account. There are some different behaviors you can use detailed here"
because when i open fresh install of the game, then click sign in button it will automatically login using main account without asking (1st time login)
at long last i can make it work anyway (its been a week try to solve this issue)
thank you very much sir

great topic what i need! i will try this

what about GetAutkToken?

in this page function

is it not enough for play fab custom login id?

The issue is that the GetAuthToken is broken in Android API 23 (I think) and higher because Google changed how logging in works. The fix I posted fixes it so that GetAuthToken actually returns a valid token and it should also work when API 30 is the new target.

in your first post, seems it change engine’s java template but the middle of your post says add android UPL xml in each project.
they need both? or xml is the recent method?

and is this right way to login google play ?

it needs more parameter to request var?

//update

  • my playfab login with google result is true but

the player account doesnt create in playfab page.

is it request param matter?

You need to add the auth token to the login with google account request. You can either add all the code to the template or you can only change the few lines and add a UPL which allows you to have multiple projects using the same template because the server will be different for each playfab project.

The whole thing is not ideal but it’s very specific to PlayFab so I don’t think Epic will take a PR because of that.

long time no see. i succeed playfab login with your post thx man.

theres lot of pre API setting in GoogleAuth and Playfab, and i should add manifest USE CREDENTIAL to ue4 package config.

by the way do you know how to use playfab chatting in android?

what i thought weird was write and fix the java template but also add UPL. but now i understood all

I don’t know how to use the chatting functionality as I haven’t had to implement it yet. The whole thing is weird and I’d really like it if Epic would fix it on their end.