play-games-plugin-for-unity
play-games-plugin-for-unity copied to clipboard
Problem authenticating when Google Play Games is not installed (or is not signed in)
Hello,
I am having a problem where the Authenticate method 'hangs' when the sign in is called if the Google Play Games (GPG) app is not installed on the device. It takes a very long time for the method to time-out (if it even does). This also occurs if trying to authenticate when GPG is installed, but was never signed in.
I am using an older packadge 0.10.12, but no mention of this issue was made in the changelog. Testing the "happy path" (GPG is installed and signed in) works as expected.
I am considering implementing a time-out, to force quit the current attempt and if it takes to long, continue without authenticating. However, I did not find a method to force-cancel the authentication.
Could you capture a bug report and share with us? If you are using a standard Android device, meaning if the device has Play Services
automatically installed, a sign-in attempt should prompt the installer when Play Games is not installed on the device.
I mostly got these reports from people using a lower-end device. I made my login a little more robust by falling back to the 'hard' login (requiring UI consent) incase the silent sign-in fails. This seems to have resolved the issue.
It seems the silent sign-in (even though it mentions it should show UI at least once) can sometimes fail to actually show the install UI. I did manage to recreate the issue a while back using AVD (using the Pixel3 as device). After a fresh install, starting my app (without Play Games installed) and at the point of the silent sign-in, it sometimes failed to show the install, resulting in an endless startup screen... However, since I added the fallback it seems to work reliably, even when using AVD.
Could you share your authentication code? The code below will prompt ui sign-in only once. But
PlayGamesPlatform.Instance.Authenticate(SignInInteractivity.CanPromptOnce, (result) =>{
// handle results
});
If you are doing only silent sign-in by using this method, then users will not see any ui.
I sign in during initialization (first time loading) like so (I also have a button in the Menu for users to sign-in / -out, but the initialization one was not doing what I had expected.
public void Initialize(string cloudSaveName, string cloudProfileName)
{
if (IsInitialized == false)
{
IsInitialized = true;
this.cloudSaveName = cloudSaveName;
this.cloudProfileName = cloudProfileName;
SubscribeToEvents();
InitializePlayGamesPlatform(BuildPlayGamesClientConfiguration());
try
{
SilentSignIn(SignInCallback);
}
catch (Exception ex)
{
GuiWriter.Instance.Write(ex.Message, Color.red, false, 5f);
}
}
}
I used to only use the silent sign-in method you provided, with some additional logic. However, since I changed it to:
private void SilentSignIn(Action<SignInStatus> callback)
{
if (Social.localUser.authenticated == false)
{
PlayGamesPlatform.Instance.Authenticate(SignInInteractivity.CanPromptOnce, async (SignInStatus result) =>
{
if (result != SignInStatus.Success)
{
// If silent sign-in fails, check if the user has previously declined to sign in.
bool isSignInDeclined = false;
if (PlayerPrefs.HasKey(signInStatusKey))
{
isSignInDeclined = Convert.ToBoolean(PlayerPrefs.GetInt(signInStatusKey));
}
// If the user hasn’t previously declined to sign in, check the internet connection and prompt interactive sign-in if internet is available
if (isSignInDeclined == false &&
await IsConnectedToTheInternet())
{
PlayGamesPlatform.Instance.Authenticate(SignInInteractivity.CanPromptAlways, (SignInStatus result) =>
{
// If the interactive sign-in is cancelled by the user, remember this as a 'decline' for any next silent sign-in attempts.
if (result == SignInStatus.Canceled)
{
PlayerPrefs.SetInt(signInStatusKey, 1);
PlayerPrefs.Save();
}
callback?.Invoke(result);
});
}
else
{
callback?.Invoke(SignInStatus.Canceled);
}
}
else
{
callback?.Invoke(result);
}
});
}
}
I have not had any issues.
However, I understood the summary of SignInInteractivity.CanPromptOnce (English is not my native language) as, first try to sign in quietly, if that does not work show the user a prompt. Though the code you reference describes exactly what is happening ;-)