简体   繁体   中英

How to use the new RegisterForActivityResult in Xamarin Android, i.e. for GoogleSignIn

I read that StartActivityForResult is deprecated and it is anyway not nice to have the callback in MainActivity.OnActivityResult() when you start the login process elsewhere.

Unfortunately I couldn't get any of the examples to work, seems Xamarin is missing essential things?

This is how it works for me in 2022

Preparation (must happen before the app is running)

var googleSignInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
    .RequestIdToken("123-321.apps.googleusercontent.com")
    .RequestEmail()
    .Build();

var googleSignInClient = GoogleSignIn.GetClient(this, googleSignInOptions);

var activityResultLauncher = this.RegisterForActivityResult(
    new ActivityResultContracts.StartActivityForResult(), 
    new ActivityResultCallback(GoogleSignInCallback));

_launchGoogleSignIn = () => activityResultLauncher.Launch(googleSignInClient.SignInIntent);

Above example is how to prepare it directly in MainActivity.OnCreate() - but I have it in the constructor of the Android implementation of my authentication service where I replaced the 2 this. by MainActivity.SharedInstance.

Unfortunately I couldn't find an IActivityResultCallback implementation anywhere, so I created my own. Hope this will be included in Xamarin some time.

public class ActivityResultCallback : Java.Lang.Object, IActivityResultCallback
{
    readonly Action<ActivityResult> _resultAction;
    public ActivityResultCallback(Action<ActivityResult> resultAction) => _resultAction = resultAction;
    public void OnActivityResult(Java.Lang.Object p0) => _resultAction((ActivityResult)p0);
}

Later I just call the Action _launchGoogleSignIn (and of course you have to handle the result somehow, like forwarding it to firebase, here's some bonus code in case you can make use of it).

async void GoogleSignInCallback(ActivityResult activityResult)
{
    var signInResult = Auth.GoogleSignInApi.GetSignInResultFromIntent(activityResult.Data);
    Console.WriteLine($@" *** {signInResult.Status} {signInResult.SignInAccount?.DisplayName}");
    if (!signInResult.IsSuccess || signInResult.SignInAccount == null)
    {
        await _alertManager.PresentSnackBarAsync("Google login canceled");
        return;
    }

    var credential = GoogleAuthProvider.GetCredential(signInResult.SignInAccount.IdToken, null);
    var authResult = await FirebaseAuth.Instance.SignInWithCredentialAsync(credential);
    var token = await authResult.User.GetIdToken(false);
    AuthToken = (token as GetTokenResult)?.Token;

    await _alertManager.PresentSnackBarAsync($"Successfully logged in with {signInResult.SignInAccount.Email}");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM