= Google Authentication project = '''All code is maintained in the !AuthRepo or the !EdApp [[https://scotnpatti.visualstudio.com/EdApp|project]]''' In this section, I'm setting out to document a fully functional Android.Auth Google Authentication project. It works! it is not ready for prime time yet as there are several things that I need to do. Including modularize it and make it work for both iOS, Windows and Android. This version focuses on Android. There are several pieces to setting this up. 1. Setup OAuth 2.0 authentication in the console.cloud.google.com see [[https://developers.google.com/identity/protocols/OAuth2InstalledApp|this]] Pay particular attention to the !RedirectUrl that they require you to use, it is different than in the next set of documentation. 1. Next, I looked instructions [[https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/oauth|here]] and code [[https://github.com/xamarin/xamarin-forms-samples/tree/master/WebServices/OAuthNativeFlow|here]](Directions current as of 6/8/2017, code on Github is, of course, newer). We are using Native=True. That just means that when it pops up the authentication for the user, it will use the Chrome browser and not your app and a web view. I had my share of problems! '''Problem 1:''' 400. That's an error. Error 400 unsupported_response_type Solution: This means that your !OAuth2Authenticator is not setup right. When creating the !OAuth2Authenticator, use the second constructor that has the token_uri in it as follows: {{{#!highlight csharp GoogleAuthData data = Configuration.Configuration.GetGoogleAuthData(); _auth = new OAuth2Authenticator( data.client_id, null, "profile", new Uri(data.auth_uri), new Uri(":/oauth2redirect"), new Uri(data.token_uri), null, true); }}} '''Problem 2:''' Google Authentication page (accounts.google.com... its in your json file you downloaded) does not go away when authentication is complete. Solution: This seems to have worked in previous version of Xamarin.Auth (prior to 1.6.0.4), but it doesn't seem to work now. I found a solution [[https://github.com/xamarin/Xamarin.Auth/issues/275|here]] which does bypass some of Xamarin.Auth functionality but still works! For posterity here is the solution: Basically, do not use the standard presenter: {{{#!highlight csharp OAuthLoginPresenter presenter = new OAuthLoginPresenter(); presenter.Login(authenticator); }}} But replace it with your own code to create the Custom Tabs. I.e. Construct the OAuth2 url authentication yourself, and call them using the Custom Tabs in .Net Standard project: {{{#!highlight csharp string url = "https://accounts.google.com/o/oauth2/v2/auth?scope=email+profile&response_type=code&redirect_uri=[your_reversed_client_id]:/oauth2redirect&client_id=[your_client_id]&access_type=offline"; ICustomTabsManager customTabsManager = DependencyService.Get(); customTabsManager.LaunchUrl(url); }}} Also create an ICustomTabManager interface in the .Net Standard project: {{{#!highlight csharp public interface ICustomTabsManager { void LaunchUrl(string url); } }}}} Create an Xamarin.Android implementation (in your android project) {{{#!highlight csharp public void LaunchUrl(string url) { Android.Support.CustomTabs.CustomTabsIntent customTabsIntent = new Android.Support.CustomTabs.CustomTabsIntent.Builder().Build(); customTabsIntent.Intent.SetFlags(ActivityFlags.NoHistory | ActivityFlags.ClearTop | ActivityFlags.SingleTop | ActivityFlags.NewTask); Activity activity = CrossCurrentActivity.Current.Activity; //NOTE: CrossCurrentActivity is a sub problem see below. customTabsIntent.LaunchUrl(activity, Android.Net.Uri.Parse(url)); } }}} And don't forget to register it with your dependency service. This can happen in your "!MainActivity" in your Android Project {{{#!highlight csharp ... DependencyService.Register(); ... }}} !CrossCurrentActivity is part of a plugin to allow you to access the current activity in an android project. You can install "Plugin.!CurrentActivity" from nuget. Then just add the initialization to your main activity as below, and you are done. {{{ ... CrossCurrentActivity.Current.Init(this, savedInstanceState); ... }}} Of course don't forget your using statements.