Hey Developers, the time has come to present the “how to” for social login with Google! I already wrote a post on how to build social login using Facebook SDK with Xamarin, you can check it out here Facebook native login with Xamarin.Forms.
This example is built with Xamarin Forms, Prism and the google sdk bindings by Xamarin Co. The great thing of using the native SDKs is that you will get the native login flow for iOS and Android.
You can find the sample code for this post in my github repo here, but be aware that it requires configurations, follow the steps on this post and use the sample project as a guide.
Google App Setup
First of all, we will have to create a app on the google developer platform, you can access it in this link, hit the create new project option.
You will name your project and that is it. Let’s get to the Xamarin projects setup. Let’s start with Android.
Xamarin Android Project Setup
1 – Xamarin Co. Binded the native SDK made by google to Xamarin.Android and Xamarin iOS, since this is the configuration for the android project. We will be using Xamarin.GooglePlayServices.Auth.
If any doubts come up, you can use the google tutorial and just translate Java to C# check it out here. The requisites according to it are the ones bellow, but I will set it up for our VS environment:
- A compatible Android device that runs Android 4.0 or newer and includes the Google Play Store or an emulator with an AVD that runs the Google APIs platform based on Android 4.2.2 or newer and has Google Play services version 11.6.0 or newer.
- The latest version of the Android SDK, including the SDK Tools component. The SDK is available from the Nuget in Visual Studio.
- A project configured to compile against Android 4.0 (Ice Cream Sandwich) or newer.
- The Google Play services SDK:
- In Visual Studio 2017 Tools > Android > Android SDK Manager.
- Scroll to the bottom of the package list and select Extras > Google Repository. The package is downloaded to your computer and installed in your SDK environment where the android SDK on you VS is installed.
After checking out the requisites, we will need a configuration file, you can get it from here.
2 – Select your app name previously created on the google developer’s console and the package name of your app
3 – After this, you will need to enable google Sign-In, for that we will need to provide google with a SHA-1 certificate.
For this example we will use a debug key, to publish your app the store, you will need a different SHA-1 key. You can read more about it here. For the SHA-1 debug key modify the command bellow, open CMD or Terminal and paste the bash:
Mac: keytool -list -v -keystore /Users/[USERNAME]/.local/share/Xamarin/Mono\ for\ Android/debug.keystore -alias androiddebugkey -storepass android -keypass android Windows: keytool -list -v -keystore "C:\Users\[USERNAME]\AppData\Local\Xamarin\Mono for Android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
4 – Finaly, you will be able to download the google-services.json file and add it to your Xamarin.Android project.
Obs: If you replace the google-services.json file on the sample project and change the Xamarin.Android package name to yours, the android sample project should work.
5 – On the Android project main activity class override the OnActivityResult method:
protected override void OnActivityResult(int requestCode, Result resultCode, Android.Content.Intent data) { base.OnActivityResult(requestCode, resultCode, data); if (requestCode ==1) { GoogleSignInResult result = Auth.GoogleSignInApi.GetSignInResultFromIntent(data); GoogleManager.Instance.OnAuthCompleted(result); } }
Xamarin iOS Project Setup
Xamarin Co. also binded the native library for Google Sign-In on iOS, that is the one we will use for our Xamarin.iOS project.
If you want, you can check the tutorial by google here and you can also checkout the getting started page of the binded SKD here.
1 – We will also need to create a configuration file for iOS, you can get to it here, the steps are very similar to the one we just did for android, you will select the App name we initially created and your app bundle id. This time there will be no need to to add SHA-1 certificate, so go ahead and enable the google Sign-In option.
2 – Download the GoogleService-info.plist file and add it to your Xamarin.iOS project.
3 – Next we will have to add the URL Scheme to our project. Open the GoogleService-info.plist and copy the REVERSED_CLIENT_ID value
4 – Then open the Xamarin.iOS info.plist file, go to the Advanced tab, create a new URL with a editor role and paste it in the URL Scheme field.
Obs: To be able run the iOS project on the simulator, you will have to enable Keychain sharing on the Entitlements.plist:Key chain sharing on iOS, needs entitlements and for that we need a valid provision profile, find out more about it here.
5 – On the iOS project AppDelegate class, FinishedLaunching add both lines:
public override bool FinishedLaunching(UIApplication app, NSDictionary options) { global::Xamarin.Forms.Forms.Init(); DependencyService.Register<IGoogleManager, GoogleManager>(); var googleServiceDictionary = NSDictionary.FromFile("GoogleService-Info.plist"); SignIn.SharedInstance.ClientID = googleServiceDictionary["CLIENT_ID"].ToString(); LoadApplication(new App(new iOSInitializer())); return base.FinishedLaunching(app, options); }
6 – Override the OpenUrl method from the AppDelegate class:
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options) { var openUrlOptions = newUIApplicationOpenUrlOptions(options); return SignIn.SharedInstance.HandleUrl(url, openUrlOptions.SourceApplication, openUrlOptions.Annotation); }
Let’s Code!
You can find all of the sample project for this tutorial here, under the GoogleNativeLogin folder. It is very simple, one page app in Xamarin.Forms that uses Dependency Injection and delegates the Login and Logout actions to the native platforms, then via an Action, we receive the Facebook User data back in the Xamarin.Forms project.
Project Tech info
- Xamarin.Forms 2.4.0
- Prism 6.3.0
- Xamarin.GooglePlayServices.Auth 42.1021.1 (On the Xamarin.Droid project)
- Xamarin.Google.iOS.SignIn 4.1.0 (On the Xamarin.iOS project)
On the Forms project, we have a contract with two signatures
public interface IGoogleManager { void Login(Action<GoogleUser, string> OnLoginComplete); void Logout(); }
Both methods are implemented on Android project and on iOS project, after the execution of the login, the OnLoginComplete method will be invoked, adding the user Google object to the ViewModel binding.
private void OnLoginComplete(GoogleUser googleUser, string message) { if (googleUser !=null) { GoogleUser = googleUser; IsLogedIn = true; } else { _dialogService.DisplayAlertAsync("Error", message, "Ok"); } }
What’s Next?
CAUSER TIP:
throw new CauserException();
References
- https://console.developers.google.com/cloud-resource-manager
- https://developers.google.com/identity/sign-in/android/sign-in
- https://github.com/xamarin/google-apis
- https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingProfiles/MaintainingProfiles.html
- https://components.xamarin.com/view/googleiossignin
- https://developers.google.com/identity/sign-in/ios/start
- https://stackoverflow.com/questions/39487368/xamarin-auth-store-keychain-not-working-after-ios10-upgrade/39576798#39576798
- https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/AddingCapabilities/AddingCapabilities.html
- https://developer.xamarin.com/samples/monodroid/google-services/SigninQuickstart/
- https://developer.xamarin.com/guides/android/platform_features/maps_and_location/maps/obtaining_a_google_maps_api_key/
- http://evgenii.com/blog/sharing-keychain-in-ios/
- https://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx
First of all I’d like to say thank you for the sample Daniel, Great Work! I ran the sample app and when I select an account, I always get an alert message that states “an error occured!”
LikeLiked by 1 person
Hey Sir, thank you! Checkout the type of the error, usually if you got this is because you left something misconfigured, if you are running the Android project, place a break point here(You should be able to see what is the error type and code that google is throwing at you) https://github.com/DanielCauser/SocialLoginSamples/blob/master/GoogleNativeLogin/GoogleNativeLogin/GoogleNativeLogin.Droid/GoogleManager.cs#L59
If you are debugging the iOS project, place a break point here(Also it is the delegate that gets called by google manager after the login completes)
https://github.com/DanielCauser/SocialLoginSamples/blob/master/GoogleNativeLogin/GoogleNativeLogin/GoogleNativeLogin.iOS/GoogleManager.cs#L41
LikeLike
me too, i debug the code, on the protected override void OnActivityResult(int requestCode, Result resultCode, Android.Content.Intent data) the resultCode is Canceled,
LikeLiked by 1 person
Anggi, make sure you are selecting your google account, Canceled status means you probably miss clicked the google account popup =P
LikeLike
hi daniel, i make sure that i click my google profile, i even deploy to my real phone, and it still the same error,
please help me on this,,
LikeLiked by 1 person
After sign I get a NullReferenceException on the Instance variable of type GoogleManager
LikeLiked by 1 person
Make sure you have the instance of the google manager being resolved to the static property of the GoogleManager service, you can see it right here: https://github.com/DanielCauser/SocialLoginSamples/blob/master/GoogleNativeLogin/GoogleNativeLogin/GoogleNativeLogin.Droid/GoogleManager.cs#L31
Also, make sure you are handling the dependency injection on the MainActivity.cs like this example https://github.com/DanielCauser/SocialLoginSamples/blob/master/GoogleNativeLogin/GoogleNativeLogin/GoogleNativeLogin.Droid/MainActivity.cs#L34
LikeLike
hi daniel, I make sure to click my google account, i deploy to my real phone, and the error is still the same,
LikeLiked by 1 person
I noticed that when the user has a profile picture, The sign in process is successful, but when you sign in a user without a profile pic, then all the exceptions start, because unlike the iOS project there is no way to check if the PhotoUrl is available or not. I have a solution though. Once again, Thank you Daniel, I really appreciate your assistance.
LikeLiked by 1 person
oh i see, the profile pict eh? 😀
if I may what is your current solution clifton sir?
LikeLiked by 1 person
Clifton sent a PR to the repo and I have merged it into the master branch, you should be able do download the changes and check it out, here is the fix merged https://github.com/DanielCauser/SocialLoginSamples/blob/master/GoogleNativeLogin/GoogleNativeLogin/GoogleNativeLogin.Droid/GoogleManager.cs#L66
LikeLike
Sorry for the late reply Anggi, but if you look in the GoogleManager.cs where the profile photo is set ‘Picture = new Uri(accountt.PhotoUrl.ToString())’, thats where the problem is, here’s a link with a pull requested to the repo that contains the changes I made to the code. Hope this helps 🙂
LikeLiked by 1 person
You are amazing, I will check out you PR and merge it into the git repo!
LikeLike
You’re welcom Daniel 🙂
LikeLike
Oh and another thing you might want to consider Anggi,don’t change anything when you’re running the sample project provided by Daniel(emphasis on the google-services.json file). The only time you need to change that file is when you’re planning on moving the code into your own project
LikeLiked by 1 person
That is correct because I have not taken down the APP on my google developer portal hehe. I might just leave it there anyway =P but I encourage people to use this code and follow the configuration steps of the post!
LikeLike
i finally got the sample working after i create my own google-services.json on the projext settings in firebase console https://console.firebase.google.com/
thanks a lot everyone
LikeLike
Awesome to hear this, thank you for the feedback Anggi!
LikeLike
hi daniel, i’ve been looking for sometime how to get the access_token?
anyone? thanks in advance..
LikeLike
Check this link out, you can see examples on how to retrieve the google token!
https://developers.google.com/identity/sign-in/android/offline-access
LikeLike
Obs: If you replace the google-services.json file on the sample project and change the Xamarin.Android package name to yours, the android.
I do not understand what you mean by this: and change the Xamarin.Android package name to yours
You can support me
LikeLiked by 1 person
So, basically what I mean is you are supposed to change the file on the project, by the one you are going to generate for yourself in the google developer portal! After this, you will need to go to the android project properties and change the package name that I have added there, by the one you created on your google developer portal, you can see it in the Step 2 of the section Xamarin Android Project Setup os the post!
LikeLike
The fact the following:
1. Download from the github repository
2. download the json file and replace the one contained in the project
3. change the package name or also called (package)
what happens is that the application starts approximately one second and then it does not work
LikeLike
HEy Anthony, did you try to run it on a Virtual Machine or in your phone?
LikeLike
thank you very much you can compile .. just a query. It is possible to login in another part of my project that is not App.cs, that is, in x.cs page of my project. I’m looking to login after a preview of my application
LikeLike
Yeah man, you can use this login page wherever you want in your APP, the sample project is a way I figured out of getting the most out of code sharing, you can see that all the calls begin and end on our shared code project, and the target platform projects handle the nuances of login flow.
LikeLike
Hello,
I am having trouble on the iOS version.
In the Google manager class when the method PresentViewController is called the _viewController is null and the app crashes. Do you know what this could be?
Thank you in advance
LikeLike
Hey Petar! Could you create an issue on the git repo? I’m trying to keep track of all the comments over there now =D
LikeLike
Issue created, thank you for a quick response.
LikeLike
I just posted a fix fox it, check it out at https://goo.gl/JjnkdG
LikeLike
Wow, awesome weblog structure! How long have you been blogging for? you made blogging look easy. The overall look of your site is excellent, as well as the content!
LikeLiked by 1 person
Hey Alex, thank you for your thoughts on the blog, it really makes me happy to have feedback from the community! I have been blogging for 5-6 months now, but I have always used blogs as a way to get information and a resource for news and updates =D. I tried to keep the layout here as simple and clean as I could, so it is easy for people to find what they ended up here for!
THank you for your feedback! Cheers!
LikeLike
Fantastic site. Plenty of useful info here. I am sending it to several pals ans additionally sharing in delicious. And certainly, thanks for your effort!
LikeLike
when I created the sample app as apk and installed it doesn’t work shows the alert with Error occured.but one thing is in debug and release mode direct run the appliication to device is working. why it makes the issues? Please figureit out
LikeLike
For those with problems (Error 10 or simply “an error occured”). You need to put the following command EXACTLY as it is, changing only the [USERNAME]:
“keytool -list -v -keystore “C:\Users\[USERNAME]\AppData\Local\Xamarin\Mono for Android\debug.keystore” -alias androiddebugkey -storepass android -keypass android”
The tutorial already says this, however I thought I had to change the storepass “android” to my actual password, and the alias “androiddebugkey” to my actual alias, but this is not correct.
This command regenerates a temporary SHA-1 (instead of your actual one), and it will work only for debug. It uses this false keystore (stored in the Xamarin directory specified in the command).
When you are about to release your project, you must change it to your correct keystore, alias and passwords, as seen here: http://www.jomendez.com/2017/08/30/ionic-2-google-sign-in-error-10-with-firebase/
To make it easier for yourself, first find the path (“C:\Users\[USERNAME]\AppData\Local\Xamarin\Mono for Android\debug.keystore”) and verify that the file debug.keystore is there. Only then, try to run the command.
LikeLiked by 1 person
Amazingly said! Thank you for sharing your thoughts, I mentioned that in the post but I think I didn’t make it as clear as you just said!
LikeLiked by 1 person
Glad to help! It is really hard to find helpful Xamarin information on the web, and your post was a godsend! This Google login was giving me nightmares, and I even had to release a project with only Facebook login, because I couldn’t make it work on time 😐
In my case, I also had to update my Visual Studio 2017 to the latest update (I didn’t know VS versions were tied to Xamarin versions, so I couldn’t download Google Repository – and to make things worse, the error was something about MD5 not matching… Damn it…
Seriously, we deserve a medal for every accomplishment using Xamarin, what a messy technology.
And greetings from Brazil (eu também sou brasileiro haha)!
Abraços!
LikeLike
Hey Daniel, Don’t know if you’ve ever come across an issue like this, but when the google login works fine in my development environment, even when I set the app to release, now that I’ve published the app I’m getting google sign in error with a status code of 10.
LikeLike
Hey clif! You need to setup the google login for the app version that you will send to the store. I mentioned it on the post: “For this example we will use a debug key, to publish your app the store, you will need a different SHA-1 key. You can read more about it here.” Here is the link! Even thought it talks about google maps shakey, it is the same process for using google longin in production 🙂 https://docs.microsoft.com/en-us/xamarin/android/platform/maps-and-location/maps/obtaining-a-google-maps-api-key?tabs=vswin#production-keys
LikeLike
Hey Daniel Thanks for you quick reply but the problem I was having was actually the exact same one stated in the link provided by @diegoleao on March 14, 2018 at 12:47 am.
LikeLike
Thanks for Native login in Facebook and Google i successfully logged in but please show me a way where i don’t need to login back when i am authenticated. Because when i close my application and again i open it then it redirects me to login page again. Please help 🙂 Beginners Question
LikeLike
Hi Daniel.
That is really a very helpful article
I have the same issue here that Clifton has
I generated the hash key on my local and test it and it worked like a charm
but my problem now is I have to upload the apk to the store, I tried to follow the link it was very confusing
is there any steps that we should follow or a better link
Thanks in advance
LikeLike
I think I found the solution, I just generate the SH1 code from the generated store key and download the new json file and everything is great now,
obs. if the app crash after this update you should go to Properties -> Android Options -> Advanced and select armeabi + x86
Thanks again Daniel
LikeLike
Hi Daniel. I hope you’re doing well. I have a problem with this `using GoogleNativeLogin.Models;` It’s not taking GoogleNativeLogin for some reason. I have GooglePlayServices.Auth added to the References form NuGet. Any idea what’s causing this? Not a lot’s there on Google about it either.
Thanks in advance for the help!
LikeLike
Hi Daniel.
I am having a problem with google login on IOS.
I am getting: “Native linking error: 1 duplicate symbol for architecture x86_64” when I add the google manager class and when i am adding :
“var googleServiceDictionary = NSDictionary.FromFile(“GoogleService-Info.plist”);
SignIn.SharedInstance.ClientID = googleServiceDictionary[“CLIENT_ID”].ToString();”
Do you have any idea about this error?
LikeLike
how to do this in xamarin forms cross platform?
LikeLike
Hey Daniel, I found a missing part in your article. GoogleService-Info.plist must set BundleResource as BuildAction. (Right click to GoogleService-Info.plist file -> Properties -> BuildAction -> BundleResource). Otherwise googleServiceDictionary will always null.
LikeLike
Hi Daniel,
Great tutorial!! The Xamarin community needs more people like you.
Is there a way to use call the device native code without converting the Application to a PrismApplication?
Thanks in advance
Jason
LikeLiked by 1 person
Yeah Jason, you can use whichever DI container you prefer.
LikeLike
thank you
LikeLike
Hey Daniel. I have xamarin.ios and Xamarin.adroid (building native app, not xamarin.forms) and shared project .core. In google manager on android it is required to have reference on Xamarin.Forms to get context in GoogleApiClient(Context context) method . Can i workaround it somehow so i dont need to keep redudant reference on xamarin.forms? Xamarin.ios project works like a charm , thanks for that ! Waiting for response though.
LikeLike
I have a problem with Prism 7.1, because the app broke up and I have a window blank when execute this code line>
public MainPageViewModel(IGoogleManager googleManager, IPageDialogService dialogService)
any idea?
I have>
Xamarin.Forms 3.5.0.169047
Prism.Unity.Forms 7.1.0.431
Prism.Core 7.1.0.431
Prism.Forms 7.1.0.431
Xamarin.GooglePlayServices.Auth 60.1142.1
LikeLike
Thank you for your topic!
1. How to login for UWP
2. How to Download and Upload a file to Google Drive API, after login!
Thank yoU!
LikeLike