Tailwind Photos: Facebook Login
In my last post on Tailwind Photos, I set up the splash screen and the buttons I want to use for signing in to the app - social media buttons for Facebook, Google, Microsoft, and Twitter. In this article, I’m going to go through the process of authenticating Facebook.
The Facebook side of things
All social media companies have their own methods for setting up authentication, and Facebook is no different. The instructions I have here are correct as of writing, but you should realize the aim of these instructions:
- Register a native mobile app for authentication.
- Get the codes needed by the SDK to configure Facebook Auth.
These may change in the future. Let’s get started!
- Log on to developers.facebook.com
- If necessary, agree to any terms and conditions to become a Facebook developer.
- Select My Apps > Create App in the top-right corner.
- Enter a display name and your contact email. I’m using
Tailwind Photos
for my display name. - Click Create App ID.
- Click Integrate Facebook Login in the scenari selector, then click Confirm.
- Click Facebook Login > Quickstart.
- Click Android.
What you will get next is a step-by-step process for integrating the Facebook Button for Android, including downloading the SDK, integrating it into your app, and generating all the keys needed. We’ll go through the same process, but in a different order. That’s mostly because I like to separate the “what to do on the website” stuff from “what to do in code”.
- Download the Facebook SDK for Android: Click Next - we don’t need to do this.
- Import the Facebook SDK: Click Next - we’ll do this during the code section.
- Tell Us about Your Android Project:
- Enter the package name (mine is
com.tailwind.app.photos
). - Enter the deep-linking activity (I’m using
com.tailwind.app.photos.activities.AuthenticatorActivity
). - Click Save
- Click Use this package name (since your package is not on Google Play yet).
- Click Continue.
- Enter the package name (mine is
- Generate a development key hash (ignore the requirement for a release key hash).
Hmm - how can we do this from Android Studio? The easiest way is to add some code temporarily to the SplashActivity
class:
DO NOT leave this code in your application. It’s a deprecated security risk. There is also a command line version (which the instructions provide) if you never want to include temporary code in your app. Always get the release key hash using the command line tool.
Run your app and watch the LogCat window:
The second line contains the development key hash. Copy it into the box provided, then click Save followed by Continue. Don’t forget to remove this code from your application.
You need to add the key hashes from every single machine you use for developing this app. To add further key hashes (including an eventual release key hash):
- Go back to the Facebook Developers page.
- Click My Apps > Your App Name
- Click Settings > Basic in the left hand nav (right below the dashboard).
- Scroll down to the bottom of the page.
- Copy the hash into the Key Hashes field (making sure you don’t delete the ones that are already there).
- Click Save Changes at the very bottom of the page.
- Enable Single Sign On for Your App: I generally turn this on because I’m bound to use it eventually.
- Click the switch icon to turn it to Yes.
- Click Save, then Next.
In the next step, your Facebook App ID and Login Protocol Scheme are shown.
The App side of things
You’re basically done with the Facebook side of things. Everything else is done in the app, so you could just click Next a bunch of times. However, the SDK does change from time to time, so you can also follow the instructions.
Add the Facebook SDK to your library
This step was #2 in the list! Edit the project-level build.gradle
:
Don’t click Sync now just yet. We need to add dependencies first. Next, edit the module-level build.gradle
file. Add the Facebook SDK to the dependencies
section:
Now you can use that Sync now button.
Edit Your Resources and Manifest
This piece is just just a copy-paste from the Facebook instructions, so I won’t bore you with the details. You need to adjust res/values/strings.xml
and the AndroidManifest.xml
file.
Log app events
The Facebook Login code suggests you should log app activations. I’m not sure my users want Facebook tracking them any more than they already do. Since I’m doing “multi-authentication”, I’ll want all the data in one place anyhow (that’s a topic for another day).
In addition, the code snippet that is shown suggests you should initialize the SDK. You no longer need to do this, so this entire step can be skipped.
Add the Facebook Login Button
Well, we’ve already done this, so let’s skip this. If you came here to learn how to do this, you need to add an ImageButton
to your layout.
Register a Callback
Finally, let’s get to some code. “Register a Callback” really means “write all the code that you need to write to make this work”. If you follow the instructions from Facebook, then your authenticator activity looks like spagetti code, and no-one like spagetti code. I prefer to isolate each authentication provider in its own manager class. This allows me to do things behind the scenes. The API surface of the manager is fairly simple:
- Set up
onSuccess
,onCancel
, andonFailure
callbacks on initialization so that we can do async responses. - Handle the
onActivityResult
response, since the SDK will go “elsewhere” and then come back with a response. - Initiate the sign-in from an
onClickHandler
for the button.
Here is my AuthenticatorActivity
class:
I can probably implement the same API surface for the other three providers. In addition, I can likely take the FacebookManager
with me to other applications. Code re-use is a wonderful thing. The onSuccess
callback returns with an AuthenticatedUser
object:
In Kotlin parlance, the AuthenticatedUser
is a common DTO. Using a data class means I get several methods created for me. I may decide to change it to a class since I don’t actually need the extra methods that are generated on a DTO. However, the savings are not significant in doing that.
Back to the problem at hand - I now have to write the FacebookManager
that conforms to the API surface I’ve described. Since the FacebookManager
is only used once, I don’t need to use a singleton. I’m interested in the AuthenticatedUser
class since I’m abstracting away authentication provider. If I were repeatedly using the access token and data returned by Facebook, I’d make this class a singleton so that the data is available across multiple activities.
Let’s go through it:
- The
onSuccess
,onCancel
, andonFailure
methods establish callbacks for later use. They returnthis
so I can use them in a fluent manner. - The
getProfile
method is an interesting one that calls the Facebook Graph API to get the name and email address. Only the name is available inProfile.getCurrentProfile()
. There are cases where the user has not provided an email (for example, when the user signs up for Facebook with a phone number from a mobile device). We’ll deal with that wrinkle later on. - The
beginSignin
method is used in the button click-handler to initiate a sign-in. - The
onActivityResult
is the callback method.
Most of the code in here is exactly what you would expect if you followed the Facebook instructions. The getProfile()
method shows how to do a graph request. I love to use the Facebook Graph Explorer to determine what fields I need to ask for and whether I have permissions to read them. However, you have to be prepared for instances where the information is not available.
Prep your emulator
You can run this app now in the emulator. When you press the Facebook logo, it will switch to a web browser, then go through the Facebook authentication before switching back to your app and moving to the MainActivity. This is pretty awesome already, as it means that a user does not need Facebook on their phone to use your app. However, you should also install the Facebook app on the emulator and then sign in to the Facebook app. Once that is complete, restart your app and go through the process again. Note how the app now switches seamlessly to the Facebook app to ask for permissions, then switches back again. It’s a much better experience.
Next steps
I’ve got three authentication providers to go, although the first one is always the hardest since you have to work out how the code flow will happen. You can find the code for this step on my GitHub repository.
Leave a comment