Xamarin.Forms Google API使用身份提供者验证用户

o8x7eapl  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(143)

I am still getting used to Xamarin.Forms and I am on very basic level. I went through many articles for my issue, but to the end couldn't resolve it. So...
Currently I am trying to add Google authentication inside my Xamarin.Forms application, which use Droid and iOS (no WP). So far I am following guide from here . I am using Xamarin.Auth to authenticate to Google.
Here is some part from my source code.

private async void GoogleSheetsButton_Tapped()
    {
        string clientId = null;
        string redirectUri = null;

        if (Device.RuntimePlatform == Device.iOS)
        {
            clientId = Constants.iOSClientId;
            redirectUri = Constants.iOSRedirectUrl;
        }
        else if (Device.RuntimePlatform == Device.Android)
        {
            clientId = Constants.AndroidClientId;
            redirectUri = Constants.AndroidRedirectUrl;
        }

        var authenticator = new OAuth2Authenticator(
            clientId,
            null,
            Constants.Scope,
            new Uri(Constants.AuthorizeUrl),
            new Uri(redirectUri),
            new Uri(Constants.AccessTokenUrl),
            null,
            true);

        authenticator.Completed += OnAuthCompleted;
        authenticator.Error += OnAuthError;

        AuthenticationState.Authenticator = authenticator;

        var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
        presenter.Login(authenticator);
    }

The problem is coming after my method complete it's work. So after my last line:

presenter.Login(authenticator);

everything looks alright and debugging I am following that compiler goes out of method without any errors, but then I receive exception, which you can see here . It's "No compatible code running".
Here some more information regarding my source code:

  • Source of "Constants" class used for client ids and URLs
public static class Constants
    {
        public static string AppName = "....";

        // OAuth
        // For Google login, configure at https://console.developers.google.com/
        public static string iOSClientId = "6.....apps.googleusercontent.com";
        public static string AndroidClientId = "6.....apps.googleusercontent.com";

        // These values do not need changing
        public static string Scope = "https://www.googleapis.com/auth/userinfo.email";
        public static string AuthorizeUrl = "https://accounts.google.com/o/oauth2/auth";
        public static string AccessTokenUrl = "https://www.googleapis.com/oauth2/v4/token";
        public static string UserInfoUrl = "https://www.googleapis.com/oauth2/v2/userinfo";

        // Set these to reversed iOS/Android client ids, with :/oauth2redirect appended
        public static string iOSRedirectUrl = "com.googleusercontent.apps.6......h:/oauth2redirect";
        public static string AndroidRedirectUrl = "com.googleusercontent.apps.6......l:/oauth2redirect";
    }
  • Source of implemented methods for on authentication complete/error, which in fact still I cannot hit because of my error
async void OnAuthCompleted(object sender, AuthenticatorCompletedEventArgs e)
    {
        var authenticator = sender as OAuth2Authenticator;
        if (authenticator != null)
        {
            authenticator.Completed -= OnAuthCompleted;
            authenticator.Error -= OnAuthError;
        }

        GoogleLoginUser user = null;
        if (e.IsAuthenticated)
        {
            var request = new OAuth2Request("GET", new Uri(Constants.UserInfoUrl), null, e.Account);
            var response = await request.GetResponseAsync();
            if (response != null)
            {
                string userJson = await response.GetResponseTextAsync();
                user = JsonConvert.DeserializeObject(userJson);
            }

            if (_account != null)
            {
                _store.Delete(_account, Constants.AppName);
            }

            await _store.SaveAsync(_account = e.Account, Constants.AppName);
            await DisplayAlert("Email address", user.Email, "OK");
        }
    }

    void OnAuthError(object sender, AuthenticatorErrorEventArgs e)
    {
        var authenticator = sender as OAuth2Authenticator;
        if (authenticator != null)
        {
            authenticator.Completed -= OnAuthCompleted;
            authenticator.Error -= OnAuthError;
        }

        var message = e.Message;
    }
  • Source of Android MainActivity where I added
public class MainActivity : FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            Forms.Init(this, bundle);
            global::Xamarin.Auth.Presenters.XamarinAndroid.AuthenticationConfiguration.Init(this, bundle);

            MobileBarcodeScanner.Initialize(Application);

            LoadApplication(new App());
        }
    }
  • Source of UrlSchemeInterceptorActivity
[Activity(Label = "CustomUrlSchemeInterceptorActivity", NoHistory = true, LaunchMode = LaunchMode.SingleTop)]
    [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataSchemes = new[] { "com.googleusercontent.apps.6......l" }, DataPath = "/oauth2redirect")]
    public class CustomUrlSchemeInterceptorActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            var uri = new Uri(Intent.Data.ToString());

            AuthenticationState.Authenticator.OnPageLoading(uri);

            Finish();
        }
    }

Here are the main articles I went through deeply => Link 1 , Link 2 and Link 3 , but still couldn't resolve the issue.
I am not sure where the error comes from, or can I can I continue debugging it to resolve issue.
Thanks in advance

Solution

  1. Change android compiler to Android 7.0 inside Android project properties. Screenshot
  2. Make sure that inside Android Manifest your target is SDK Version. Screenshot
  3. Update all "Xamarin.Android.*" nuget packages to minimum version 25.4.0.1. Most probably they're currently to 23.3.0. I found problems with dependencies on updating it, so I make manual upload. I went and download manually each package and move it to packages folder. Then I created my own package source and give for path my folder packages and I used it to install already downloaded NuGet packages. Screenshot
  4. After that my issue was solved.
0yg35tkg

0yg35tkg1#

请将您的Android SDK更新为API 24或更高版本,并将其设置为项目的编译版本。并将自定义选项卡及其依赖项的引用程序集更新为v25.x.x。

相关问题