Closed JohnnyWasabi closed 4 weeks ago
Hi, unfortunately we haven’t got reports about google ID logins so far. But on the top of my head, there is a step that might make a difference. In the Dev Portal of your app, was google ID set as a identity provider.?
Yes, assuming you mean the EOS dev portal. I added Google as an Identity Provider and I setup the sandboxes to allow Google as Identity provider. I setup two versions of Google Identity Provider: one with the developer upload key client ID and one with the Google signing key client ID (I set up two OAuth Android clients on the Google Play Console, one for each signing key). I currently have all the sandboxes assigned to the developer upload key version of the Identity Provider.
Hello, let's go through the questions.
Am I following the correct guides (linked above)?
That should be right since it is an official document.
Should I use the older "Google" plugin or the newer "Google Play Games" plugin?
This one we aren't quite sure, but they should work if they provide the right tokens for login
Do I need to have a Unity Cloud Project and Authentication plugin setup to use EOS Connect API?
We don't think it is a hard dependency to use Unity Cloud.
Has anyone else used PlayEveryware for Android mobile with Google Identity provider?
We did implement connect interface using google IDs, but haven't really got any reports with problems specifically about logging in.
Should I use EOS C# interface instead of the PlayEverware plugin for Android mobile?
The PlayEveryWare Unity plugin for EOS includes EOS C# interface and uses it for login code in the samples
So, with the identity providers being set. The next clues we'd like to get is how you implemented the login code. Have you tried the samples provided with the eos unity plugin upm?
I dove into our task manage tool and realized that our google ID connect was only tested internally but wasn't fully released. We will try our best to get it fully tested. While in the meantime, because all connect login types follow a similar pipeline, if you have tried to implement google ID following the similar structure but still wasn't able to connect, please share your findings with us.
It would be great to see your test code that uses Google as identity provider. Here is effectively the code that I'm running (as it currently stands, I've tried variations):
// At startup, our Achievements Manager activates Google Play Games and authenticates on Google Platform:
private void Start()
{
GooglePlayGames.PlayGamesPlatform.Activate(); // At startup we do this to sign in for Achievements support.
GooglePlatform?.Authenticate(UponGoogleAuthentication);
}
private void UponGoogleAuthentication(GooglePlayGames.BasicApi.SignInStatus status)
{
switch (status)
{
case GooglePlayGames.BasicApi.SignInStatus.Success:
Debug.Log($"Google Social auth'd as {Social.localUser.userName} (ID {Social.localUser.id})", gameObject);
GooglePlatform?.LoadAchievements(UponSocialAchievementsLoaded);
break;
case GooglePlayGames.BasicApi.SignInStatus.Canceled:
Debug.Log("User canceled Google Social auth");
break;
case GooglePlayGames.BasicApi.SignInStatus.InternalError:
Debug.LogWarning("Google Social authentication failed", gameObject);
break;
default:
Debug.LogError($"Unrecognized status code from Google Social auth attempt: {status}");
break;
}
}
// ... Later ... When the user starts multiplayer game, StartLogin() is called.:
public string Token;
public string Error;
private void StartLogin()
{
// Activate is called again (was called at startup by Achievments Manager)
GooglePlayGames.PlayGamesPlatform.Activate();
DoLogin();
}
async void DoLogin()
{
await UnityServices.InitializeAsync();
await LoginGooglePlayGames();
//await SignInWithGooglePlayGamesAsync(Token);
StartConnectLogin(Token);
}
public Task LoginGooglePlayGames()
{
var tcs = new TaskCompletionSource<object>();
PlayGamesPlatform.Instance.Authenticate((success) =>
{
if (success == SignInStatus.Success)
{
Debug.LogWarning($"> > > > > > > > > > >Google Social auth'd as {Social.localUser.userName} (ID {Social.localUser.id})");
Debug.Log("Login with Google Play games successful.");
PlayGamesPlatform.Instance.RequestServerSideAccess(true, code =>
{
Debug.Log($"Authorization code is {(code != null ? code : "<null>")}");
Token = code;
// This token serves as an example to be used for SignInWithGooglePlayGames
tcs.SetResult(null);
});
}
else
{
Error = "Failed to retrieve Google play games authorization code";
Debug.Log("Login Unsuccessful");
tcs.SetException(new Exception("Failed"));
}
});
return tcs.Task;
}
async Task SignInWithGooglePlayGamesAsync(string authCode)
{
try
{
await AuthenticationService.Instance.SignInWithGooglePlayGamesAsync(authCode);
Debug.Log($"PlayerID: {AuthenticationService.Instance.PlayerId}"); //Display the Unity Authentication PlayerID
Debug.Log("SignIn is successful.");
}
catch (AuthenticationException ex)
{
// Compare error code to AuthenticationErrorCodes
// Notify the player with the proper error message
Debug.LogException(ex);
}
catch (RequestFailedException ex)
{
// Compare error code to CommonErrorCodes
// Notify the player with the proper error message
Debug.LogException(ex);
}
}
void StartConnectLogin(string code)
{
Debug.Log($"StartConnectLogin(): Authorization code is {(code != null ? code : "<null>")}");
string googleIdToken = code;
// This token serves as an example to be used for SignInWithGooglePlayGames
EOSManager.Instance.StartConnectLoginWithOptions(ExternalCredentialType.GoogleIdToken,
googleIdToken, //((PlayGamesLocalUser)Social.localUser).GetIdToken(), //Encoding.UTF8.GetString(Social.localUser.id, 0, appleIDCredential.IdentityToken.Length)).Replace("-", ""),
displayname: Social.localUser.userName,
onloginCallback: GoogleEpicLoginCallback);
Debug.Log("MultiplayerModeController.cs: After call to StartConnectLoginWithOptions()");
//LogInSuccess();
//Encoding.UTF8.GetString(appleIDCredential.IdentityToken, 0, appleIDCredential.IdentityToken.Length);
}
I didn't see an example for Google in the EOS Samples, so I've not tried them. I'll take a look at the SignInWithApple sample since I do also need to support Apple sign in on iOS devices. I was hoping to get Android working first because it is easier to iterate on Android devices.
Nice, let us know if SignInWithApple works for you, in the meantime we will track google login as a new feature.
My attempt to sign in with Apple using the sample code from PlayAnyware (EOSSignInWithAppleManager.cs) to get the token resulted in and InvalidToken error result from EOSManager.Instance.StartConnectLoginWithOption(). This leads me to suspect something is wrong in my setup either on the Apple side or the EOS side. I'm looking into that.
Back on the Google setup, should I be using the OAuth for game or web app. I set up both and game app was not working so I'm currently using web app--also because Unity Authentication required a client secret which was only available through a web app. But since you said you don't think Unity Cloud is required which was needed for Unity Authentication, I'm thinking maybe I should be using the game OAuth option.
I'm also experiencing problems authenticating on Android. As far as I can tell, the authentication code provided by the Play Games plugin from RequestServerSideAccess
is not a token that is supported in combination with ExternalCredentialType.GoogleIdToken
.
It needs to first be exchanged for an access token like described here: https://developers.google.com/games/services/android/offline-access#exchange_the_server_auth_code_for_an_access_token_on_the_server I assume this is something that needs to be added support for from Epic's end.
@JohnnyWasabi I got Apple Sign In up and running; the last critical issue in getting a valid token for me was to switch to a Live deployment rather than Dev. Might be the same for you :)
I would have liked to be able to sign in seamlessly with Play Games, but for now I'll just display the web account portal instead.
I will share the feedback I have researched over the past few days.
The result is LogEOSAuth(Error): Invalid parameter EOS_Auth_Credentials.ExternalType reason: invalid type.
I reimplemented the above Java sample in NodeJS and verified it on the server side, but I could not obtain an idToken.
We were digging through documents about google ID connect, so far, our understanding is that: Google Play Authentication is not the same as Sign in with Google, and the googleId that EOS connect supports is from Sign in with Google.
As for AppleID login, our implementation has some small errors in the previous release. They are identified and fixed in this PR They will be included in the next release.
We are looking to implement google login into our login sample, in the meantime, please let us know if you have any new discoveries. Thank you all for sharing information on this issue.
Here is the summary so far. Please correct me if I’m wrong.
With EOS SDK, you’ll be able to log in using a Google ID token via OpenID.
As for the play-games-plugin-for-unity, it’s not gonna be able to log into EOS anytime soon. (As far as I know, Epic’s forum has clearly denied any plans to support GooglePlayGames.)
If you need an EpicAccountId to use features like Friend or Presence, you’ll have to get a Google ID token through Android’s CredentialManager (since all the older APIs are deprecated). You could also consider using other OpenID providers.
If you don’t need these features, it’s enough to just connect to the Connect interface with a Device Id.
As a note, Firebase and Playfab have a login flow that gets a unique identifier from OAuth2's scope, but Epic only allows login with OpenID.
If you don’t need these features, it’s enough to just connect to the Connect interface with a Device Id.
Unfortunately Device IDs on Android and iOS devices are deleted when uninstalling the application. So if you need any kind of persistency, you'll need to link an external account.
Source: https://dev.epicgames.com/docs/game-services/eos-connect-interface#deletion-of-device-id-credentials
We have tried out some packages to implement google id. We tried i5toolkit and GoogleSignIn for Unity. Both attempts didn't cut it on Android. (On PC though it worked) So we are looking to try out CredentialManager. Wondering if users on this thread had successful results?
Below is the core part of the code for obtaining the IdToken on Android 12 and Android 13. There are missing classes, so it won't work as-is, but you should be able to get an overview of it.
For actual production use, it's better to cache the authentication result with AuthorizationClient, but for testing Eos login, IdToken can be obtained using only CredentialManager.
interface GoogleSignInListenerInternal { // Unity side callback using "AndroidJavaProxy".
void OnSuccess(String idToken, String email);
void OnFail(int errorCode);
void OnException(Exception exception);
}
public class GoogleSignInClient {
static final int NO_GOOGLE_CREDENTIALS = 1;
public static void signIn(GoogleSignInListenerInternal listener, String clientId, boolean autoLogin) {
try {
Context context = UnityActivity.get();
CredentialManager manager = CredentialManager.create(context);
GetGoogleIdOption options = new GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(autoLogin)
.setServerClientId(clientId)
.setAutoSelectEnabled(autoLogin).build();
GetCredentialRequest request = new GetCredentialRequest.Builder().addCredentialOption(options).build();
manager.getCredentialAsync(context, request, null, Executors.newSingleThreadExecutor(),
new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
@Override
public void onResult(GetCredentialResponse response) {
try {
Credential credential = response.getCredential();
if (credential instanceof CustomCredential
&& credential.getType().equals(GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL)) {
GoogleIdTokenCredential idTokenCredential = GoogleIdTokenCredential.createFrom(credential.getData());
String idToken = idTokenCredential.getIdToken();
String email = idTokenCredential.getId();
listener.OnSuccess(idToken, email);
return;
}
listener.OnFail(NO_GOOGLE_CREDENTIALS);
} catch (Exception e) {
listener.OnException(e);
}
}
@Override
public void onError(@NonNull GetCredentialException e) {
listener.OnException(e);
}
});
} catch (Exception e) {
listener.OnException(e);
}
}
}
dependencies {
implementation 'com.google.android.gms:play-services-auth:21.2.0'
implementation "androidx.credentials:credentials: 1.3.0-rc01"
implementation "androidx.credentials:credentials-play-services-auth:1.3.0-rc01"
implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1"
}
Since the code was written some time ago, there may be some overlooked details.
We will close this issue for now as it is tracked as a feature task.
I've not been able to find a tutorial that specifically shows how to use EOS Connect API with Google as an identity provider for Android mobile platform. I've pieced together the two halves from other platform tutorials so that the code obtains a Google ID Token and passes it to the PlayEveryware EOSManager StartConnectLoginWithOptions() method, but I get an error for "Invalid Token".
I've tried both the Unity Google Plugin and the Google Play Games plugin as described in the Unity Authentication docs. Both get the Invalid Token error.
I have setup the game on EOS and on Google Play Console and on Google Cloud Platform and on Unity Cloud (as a cloud project). I'm not sure if the Unity Cloud project is necessary, but I was following this Unity Tutorial for Authentication with Google Play Games, and it said to do all those things.
I realize there are many parts of all that setup and an error in any one part could cause my problem. I've gone over the setup with other eyes helping me and we could not spot any discrepancies. My questions are:
Thanks in advance for any helpful tips or directions.