Closed husseinshaib1 closed 4 years ago
I'm having the same issue. Bizarrely, I had this working a couple nights ago, but as of this evening both idToken and accessToken are null after authenticating, but CurrentUser is populated, as well as IsLoggedIn showing 'true'.
Did you figure it out @husseinshaib1?
@kylewhittington yes I've got everything working fine. share some code to check of you are missing something.
Code for the method that does authentication below. I'm using Firebase for authentication after the fact -- ie. Google login first, then exchange access token for a Firebase JWT. However, the access token is not populated when coming back from the Google auth, with a 'completed' status.
The strange this is that implementation was almost certainly working a few days ago. Of course outside of this I have the google-services.json in the project (and checked it is up to date), and I am initialising the plugin within the MainActivity after OnCreate.
Why would GoogleService not yet have those values populated, when authentication is over? What did you find was wrong with yours?
Any help is much appreciated!
private async Task ExecuteLoginWithGoogleCommand()
{
IsBusy = true;
try
{
if (_googleService.IsLoggedIn)
{
_googleService.Logout();
}
EventHandler<GoogleClientResultEventArgs<GoogleUser>> userLoginDelegate = null;
userLoginDelegate = async (object sender, GoogleClientResultEventArgs<GoogleUser> e) =>
{
switch (e.Status)
{
case GoogleActionStatus.Completed:
#if DEBUG
var googleUserString = JsonConvert.SerializeObject(e.Data);
Debug.WriteLine($"Google Logged in succesfully: {googleUserString}");
#endif
var currenUser = _googleService.CurrentUser; // This is populated
var idToken = _googleService.IdToken; // This is null
var accessToken = _googleService.AccessToken; // This is null
var isLoggedIn = _googleService.IsLoggedIn; // This is true
var credentials = await FirebaseAuthService.LoginWithGoogle(accessToken);
if (credentials.AccessToken != null)
{
await AccountStore.SaveCredentialsAsync(credentials);
App.GetMainPage();
}
else
{
Dialogs.Toast("We were unable to log you in using your Google account. Something went wrong.");
}
break;
case GoogleActionStatus.Canceled:
await App.Current.MainPage.DisplayAlert("Google Auth", "Canceled", "Ok");
break;
case GoogleActionStatus.Error:
await App.Current.MainPage.DisplayAlert("Google Auth", "Error", "Ok");
break;
case GoogleActionStatus.Unauthorized:
await App.Current.MainPage.DisplayAlert("Google Auth", "Unauthorized", "Ok");
break;
}
_googleService.OnLogin -= userLoginDelegate;
};
_googleService.OnLogin += userLoginDelegate;
await _googleService.LoginAsync();
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
IsBusy = false;
}
Same issue here, this is my code.
var result = await CrossGoogleClient.Current.LoginAsync();
if (result.Status == GoogleActionStatus.Completed)
{
string token = CrossGoogleClient.Current.IdToken);
}
I think I've followed all the steps correctly. What could possibly be wrong? @husseinshaib1 any ideas?
here is the code I am usign:
`var response = await CrossGoogleClient.Current.LoginAsync(); switch (response.Status) { case GoogleActionStatus.Completed: IGoogleClientManager _googleService = CrossGoogleClient.Current;
string googleIdToken = _googleService.IdToken;
string googleAccesstoken = _googleService.AccessToken;
var firebaseToken = await DependencyService.Get<IFacebookAuthenticatorR>().GetFirebaseTokenFromgoogleCredentials(googleIdToken, googleAccesstoken);
this.ManageLogin(firebaseToken);
break;
case GoogleActionStatus.Canceled:
await App.Current.MainPage.DisplayAlert("Google Auth", "Canceled", "Ok");
break;
case GoogleActionStatus.Error:
await App.Current.MainPage.DisplayAlert("Google Auth", "Error", "Ok");
break;
case GoogleActionStatus.Unauthorized:
await App.Current.MainPage.DisplayAlert("Google Auth", "Unauthorized", "Ok");
break;
}`
`public async Task
IAuthResult user = await FirebaseAuth.Instance.SignInWithCredentialAsync(credential as AuthCredential);
//var instanceIdResult = await FirebaseInstanceId.Instance. .GetInstanceId().AsAsync<IInstanceIdResult>();
//var refreshtoken = instanceIdResult.Token;
var token = user.User.GetIdToken(false);
//Tasks.await(token);
Firebase.Auth.GetTokenResult tokenResult = token.Result as Firebase.Auth.GetTokenResult;
return tokenResult.Token;
}
catch (FirebaseAuthInvalidUserException e)
{
e.PrintStackTrace();
return "";
}
}`
also make sure that in firebase console you are specifying the sha-1 for the keystore you are using to sign the apk. let me know if there is still any issue
OK, I've discovered a couple things.
Without initialising the GoogleClientManager with your ClientId, you won't get the idToken back. There is documentation here about that here: https://github.com/CrossGeeks/GoogleClientPlugin/blob/master/docs/GettingStarted.md -- under the 'Enabling Server Auth Code or RequestIdToken Programmatically (Optional)' which is why I previously skipped it.
However, the main reason you can't access the AccessToken straight after it is authenticated has got to do with a slightly async thing happening in the background which takes a few hundred milliseconds to return, and is thus not yet populated. This is terrible but to hack this all you have to do is sleep the thread by a few hundred milliseconds (I did 500). I believe it's because of this line:
I believe if this code was changed to run sync rather than pushing into a new task, then it would follow through without having to do the delay. Not sure what the implications of that are, but I'm pretty sure that is why we're seeing this issue.
I have no idea why @husseinshaib1's is working without this!
My updated code below:
private async Task ExecuteLoginWithGoogleCommand()
{
IsBusy = true;
try
{
if (_googleService.IsLoggedIn)
{
_googleService.Logout();
}
EventHandler<GoogleClientResultEventArgs<GoogleUser>> userLoginDelegate = null;
userLoginDelegate = async (object sender, GoogleClientResultEventArgs<GoogleUser> e) =>
{
switch (e.Status)
{
case GoogleActionStatus.Completed:
#if DEBUG
var googleUserString = JsonConvert.SerializeObject(e.Data);
Debug.WriteLine($"Google Logged in succesfully: {googleUserString}");
#endif
await Task.Delay(500);
var accessToken = _googleService.AccessToken;
var credentials = await FirebaseAuthService.LoginWithGoogle(accessToken);
if (credentials.AccessToken != null)
{
await AccountStore.SaveCredentialsAsync(credentials);
App.GetMainPage();
}
else
{
Dialogs.Toast("We were unable to log you in using your Google account. Something went wrong.");
}
break;
case GoogleActionStatus.Canceled:
await App.Current.MainPage.DisplayAlert("Google Auth", "Canceled", "Ok");
break;
case GoogleActionStatus.Error:
await App.Current.MainPage.DisplayAlert("Google Auth", "Error", "Ok");
break;
case GoogleActionStatus.Unauthorized:
await App.Current.MainPage.DisplayAlert("Google Auth", "Unauthorized", "Ok");
break;
}
_googleService.OnLogin -= userLoginDelegate;
};
_googleService.OnLogin += userLoginDelegate;
await _googleService.LoginAsync();
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
IsBusy = false;
}
Please try on latest version should be fixed
hi, I am trying to get the idtoken and accessToken but both are null. I followed the documentation and initialized the plugin with client id but no success. any suggestions?