User authentication can be a powerful addition to your Android app. Once you can identify the individual people who are using your app, you can customize your app’s content, potentially delivering an experience that feels as though it was designed with a specific user in mind.

But authentication isn’t just a way of delivering a more compelling, highly-personalized user experience. Depending on the kind of app you’re creating, the ability to identify your users may be required for your app to function at all – good luck developing a chat, email or social media app if you have absolutely no way of telling who anyone is!

Traditionally, authentication has required the user to complete a registration form, usually creating a username and password in the process. However, with the rise of social networks there’s now a much quicker and easier way of getting users signed into your app: using an account they’ve already created with an external authentication provider, such as Facebook or Twitter.

In this tutorial, I’m going to show you how to replace the time-consuming and frustrating user registration form, with a simple ‘Sign in with Facebook’ or ‘Sign in with Twitter’ button, using Firebase Authentication and the Fabric platform.

Introducing Firebase Authentication

User authentication has the potential to greatly improve the user experience, but implementing this functionality has traditionally required you to setup your own servers and design a custom authentication system. This authentication system must be capable of verifying the user’s credentials and storing them securely, but it also needs to handle all the miscellaneous tasks that surround authentication, such as managing password reset requests. Even after you’ve got everything up and running, the hard work is far from over as your system and servers will require ongoing maintenance and updates if they’re going to continue running smoothly.

To help you add authentication to your app without having to implement your own servers and systems, in this tutorial we’re going to be using Firebase Authentication, a backend-as-service (BaaS) platform that effectively provides servers and an authentication system out-of-the-box, leaving you free to focus on what really matters: providing a great experience once your users have signed in.

The other major benefit of using Firebase Authentication, is that it’s designed to play nicely with other Firebase services, so once you’ve implemented Authentication you’ll be in an ideal position to use additional Firebase services. In particular, Firebase Cloud Storage can help you store and deliver user-generated content, and you can use Firebase Realtime Database Rules to control the information your authenticated users have access to, as well as the actions they can perform, for example if you’re developing an email app then you can use Database Rules to prevent users from reading emails that aren’t addressed to them.

Why should I care about user authentication?

Firebase Authentication may remove a lot of the complexity that’s traditionally surrounded user authentication, but adding authentication to your app is still a multi-step process.

To help you decide whether giving users the ability to log into your app with their existing Twitter or Facebook credentials really is worth the time and effort, let’s take an in-depth look at some of the ways in which authentication can improve the user experience.

1. It’s the only way you can personalize the user experience

Once you’ve identified a user, you can potentially customize every part of your app in order to provide a better experience for that specific user. For example, you might filter your app’s content based on the user’s location or the pages they’ve liked on Facebook, or you might move their most frequently-used actions to the top of your application’s menus. Even something as simple as importing the user’s profile picture can add to the overall user experience.

As a general rule, the more information you have access to, the more closely you can tailor the user experience. This is where external authentication providers have a huge advantage: if the user signs in via a social network then your app will have access to much more information, compared to if the user signed in with their email address. For example, if a user signs in with Facebook then your app will potentially have access to information ranging from their date of birth, to their location, work history, friends list, and all the pages they’ve liked, which is a huge amount of information to work with.

2. It’s far easier than filling in a registration form

Performing any lengthy or complex interactions on the smaller screen of a smartphone or tablet is a frustrating experience, particularly since we tend to use our mobile devices on the go. With his in mind, your users probably aren’t going to be thrilled by the prospect of completing a lengthy registration form before they can even start using your app.

Authenticating your users via an external provider like Facebook or Twitter allows you to replace the frustrating and time-consuming registration form with a quick and easy, one-tap ‘Sign in with Twitter/Facebook’ button. Plus, allowing the user to log in with their existing credentials means that your app isn’t adding to the long list of passwords they’re probably already struggling to remember on a day-to-day basis.

3. It gives you the chance to re-engage users who’ve uninstalled your app

Once you’ve authenticated a user, you typically have a way of communicating with that user outside of the application context. This may not seem like a big deal when you can just communicate with a user inside your application via things like dialogs and notifications, but it becomes invaluable if that user ever decides to uninstall your app. Since you still have a way of communicating with them, there’s still a chance that you can re-engage them, for example if you have access to the email address associated with a user’s Facebook account, then you might decide to send them an email when you next update your app, just to make sure they’re fully aware of all the great new features they’re missing out on.

4. It’s an important part of providing a seamless user experience, across devices and potentially across platforms

Hopefully your users will enjoy your app so much that they’ll install it across all their devices, and user authentication is an essential part of preparing for this best-case scenario. Allowing users to sign in means that your app will be able to identify a user regardless of the device they’re currently using. Since all the authentication methods supported by Firebase are cross-platform, even if you release your app across multiple operating systems then your app have no problems recognizing an individual, regardless of the device they’re currently using.

Being able to identify the user based on their login credentials is also crucial if that user ever has to re-install your app. Maybe something goes wrong with the user’s device and they wind up losing all their data, or maybe it’s a happier scenario and they’ve just purchased a new smartphone – whatever the details, they just have to download your app, sign in with their Facebook or Twitter account, and they can pick up exactly where they left off.

Adding Firebase Authentication to your Android project

Regardless of whether you decide to use Twitter or Facebook authentication, whenever a new user signs into your app you’ll want the Firebase Console to receive a notification and create a unique ID for that user.

To create this connection between your app and the Firebase Console, you need to create a new Firebase Console project and enter some information about your app, then add the Firebase Authentication library as a project dependency.

You’ll need to perform this setup regardless of the external provider you’re authenticating with:

  • Sign up for a free Firebase account.
  • Log into your Firebase Console.
  • Click the ‘Create New Project’ button.
  • Give your project a name, then click ‘Create Project.’
  • Select ‘Add Firebase to your Android App.’
  • Enter your project’s package name.

At this point, the Firebase Console dialog will ask you to enter your project’s debug signing certificate (SHA-1). To get this certificate, open your project in Android Studio and then:

  • Select Android Studio’s ‘Gradle’ tab (where the cursor is positioned in the following screenshot).
  • In the new panel that appears, select your application’s root, followed by ‘Tasks >Android > Signing Report.’

  • Android Studio’s ‘Run’ window should open automatically, but if it doesn’t then you can open it manually by clicking the ‘Run’ tab.
  • Select the ‘Toggle tasks executions/text mode’ button.
  • The ‘Run’ panel will update to display lots of information about your project – including its SHA-1 fingerprint.

  • Paste this SHA-1 fingerprint into the Firebase Console dialog, then click ‘Add App.’
  • When prompted, select ‘Download google-services.json.’ Click ‘Continue.’
  • Switch back to Android Studio and make sure you have the ‘Project’ view selected. Drag the newly-downloaded google-services.json file into your project’s ‘app’ directory.

Next, open your project-level build.gradle file and add the Google Services plugin to the buildscript dependencies:

buildscript {
   repositories {
     jcenter()
   }
   dependencies {
       classpath 'com.android.tools.build:gradle:2.2.2'
       classpath 'com.google.gms:google-services:3.0.0'

Open your module-level build.gradle file and add the Google Services plugin to the bottom of this file:

apply plugin: 'com.google.gms.google-services'

Then, add the Firebase Authentication library as a dependency:

dependencies {
   compile fileTree(dir: 'libs', include: ['*.jar'])
   androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
       exclude group: 'com.android.support', module: 'support-annotations'
   })
   compile 'com.android.support:appcompat-v7:25.2.0'
   testCompile 'junit:junit:4.12'
   compile 'com.google.firebase:firebase-auth:10.2.0'
}

When prompted, sync your changes. If you do encounter any errors, then double-check that you’ve added Firebase’s google-services.json file to the correct section of your project (it should appear in your project’s ‘apps’ directory). You should also open the SDK Manager and check that you’re running the latest versions of both Google Play Services and the Google Repository.

With this setup out of the way, you’re ready to implement your authentication provider of choice – let’s start with Facebook Login.

Authenticate with Facebook

In order to successfully implement Facebook Login, you’ll need to complete the following steps:

  • Add the Facebook SDK to your project.
  • Create a Facebook Developer account and register your Android app with this account.
  • Copy the App ID and App Secret from your Facebook Developer account, and paste it into both the Firebase Console and your Android application.
  • Paste the OAuth redirect URI from your Facebook Developer account, into the Firebase Console. This redirect URI is essentially a security mechanism that helps prevent redirect attacks by providing a whitelisted URI that should be used to direct the user back to your app, after they’ve completed the Facebook Login dialog.
  • Generate a key hash that’ll be used to authenticate the interactions that happen between the Facebook application and your own app.
  • Create a ‘Log into Facebook’ button in your Android app, and implement the code that’ll handle login events.

Add the Facebook SDK to your project

Start by opening your project’s module-level build.gradle file and adding the latest version of the Facebook SDK for Android to the dependencies section:

dependencies {
   compile fileTree(dir: 'libs', include: ['*.jar'])
   androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
      exclude group: 'com.android.support', module: 'support-annotations'
   })
   compile 'com.android.support:appcompat-v7:25.2.0'
   testCompile 'junit:junit:4.12'
   compile 'com.google.firebase:firebase-auth:10.2.0'

   // Add the Facebook SDK
   compile 'com.facebook.android:facebook-android-sdk:4.20.0'

Facebook publish their SDK to the Maven Central repository, so you’ll need to configure your project to use mavenCentral(). Open your project-level build.gradle file and add mavenCentral to both repository sections:

buildscript {
   repositories {
     jcenter()
     mavenCentral()
   }

And then:

allprojects {
   repositories {
     jcenter()
     mavenCentral()
   }
}

Register with Facebook Developers and get your App ID

Next, head over to the Facebook Developers website and create your Developer Account. Once you’re logged in, register your Android project by:

  • Clicking the ‘Create App’ button in the upper-right corner of your Facebook Developer account.
  • Give your project a name, select a category, and then click ‘Create App ID.’ This creates a new page within your Facebook Developer account, dedicated to this particular application.
  • Select ‘Dashboard’ from the left-hand menu.

This section of the console contains your App iD, plus the App Secret, which you’ll need to add to the Firebase Console and to your actual Android application.

In Android Studio, open your project’s Manifest, create a facebook_app_id string, and set it to the value of your App ID.

<string name="facebook_app_id">YOUR-UNIQUE-APP-ID</string>

You’ll also need to add the App ID plus the App Secret to your Firebase Console, so make sure you have the correct project open in Firebase Console, and then:

  • Find the ‘Authentication’ card and select its accompanying ‘Get started’ button.
  • Select the ‘Sign-In method’ tab.

  • Select ‘Facebook’ from the list. In the subsequent dialog, drag the slider into the ‘Enable’ position.
  • Copy the App ID and the App Secret from your Facebook Developer account, and paste them into the appropriate fields in the Firebase Console dialog.
  • The Firebase Console dialog also contains an OAuth redirect URI that you need to add to your Facebook Developer account. Make a note of this URI, and then click ‘Save’ to close the Firebase dialog.

Generate a Key Hash

Facebook uses a key hash to authenticate all the interactions that happen between your app and the Facebook application. When you’re developing your app, you’ll typically generate a hash using your default debug keystore, although when it’s time to release your app you’ll need to update this to a release hash.

If you’re a Mac user then you can generate a hash key using the debug keystore, by opening your Terminal and running the following command:

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

If you’re a Windows user, then you’ll need to launch the Command Prompt and enter the following:

keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl
Base64

When prompted, enter the password (for debug.keystore, this is “android”) and the Terminal or Command Prompt will return a 28 character key hash.

Next, flick back to your Facebook Developer account and:

  • Select ‘Add Product’ from the left-hand menu.
  • Find ‘Facebook Login’ and click its accompanying ‘Get Started’ button. Select ‘Android.’
  • You’ve already completed a lot of the steps in this dialog, so keep clicking ‘Next’ until you reach the ‘Tell us about your project’ box. Enter your project’s package name and default class Activity name, then click ‘Save,’ followed by ‘Continue.’
  • You’ll then be asked to enter a hash key. Enter the debug hash you just generated, then click ‘Save changes’ and ‘Continue.’

The next few screens contain code snippets that you can add to your app, but there’s one final bit of setup we need to complete before we can start coding: adding the oAuth redirect URI to the Facebook Developer account. Note, if you didn’t jot down this URI value then you can find it in the Firebase Console; select the ‘Sign-In Method’ tab and then give ‘Facebook’ a click to open the dialog containing your URI.

To enter your URI into your Facebook Developer account, select ‘Facebook Login’ from the left-hand menu. On the subsequent screen, paste the URI into the ‘Valid OAuth redirect URI’ field box, then click ‘Save changes.’

Designing the Facebook Login experience

The easiest way to implement the Facebook Login flow, is to use the LoginButton component that’s included in the Facebook SDK.

LoginButton is a custom implementation of Android’s standard Button widget, so you can simply drop this button into your layout resource file, for example:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/activity_main"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:orientation="vertical"
   tools:context="com.jessicathornsby.facebooklogin.MainActivity">

<com.facebook.login.widget.LoginButton
       android:id="@+id/login_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />
</LinearLayout>

When the user presses this button, you’ll need to create a callback manager that’ll handle the results of the login attempt (this will either by onSuccess, onError or onCancel).

In the following code, I’m implementing these callbacks, but I’m also printing the user’s ID and Auth Token to Android Studio’s Logcat Monitor, so you can see hard proof that a login attempt has been a success.

package com.jessicathornsby.facebooklogin;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import android.content.Intent;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
   private CallbackManager callbackManager;
   public static final String TAG = "MainActivity";

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       // Create a callbackManager//
       setContentView(R.layout.activity_main);

       // Initialize your instance of callbackManager//
       callbackManager = CallbackManager.Factory.create();

      // Register your callback//
      LoginManager.getInstance().registerCallback(callbackManager,

      // If the login attempt is successful, then call onSuccess and pass the LoginResult//
      new FacebookCallback<LoginResult>() {
          @Override
          public void onSuccess(LoginResult loginResult) {
              // Print the user’s ID and the Auth Token to Android Studio’s Logcat Monitor//
                  Log.d(TAG, "User ID: " +
                        loginResult.getAccessToken().getUserId() + "\n" +
                        "Auth Token: " + loginResult.getAccessToken().getToken());
          }

          // If the user cancels the login, then call onCancel//
          @Override
          public void onCancel() {
          }

          // If an error occurs, then call onError//
          @Override
          public void onError(FacebookException exception) {
          }
     });
   }

   // Override the onActivityResult method and pass its parameters to the callbackManager//
   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       callbackManager.onActivityResult(requestCode, resultCode, data);
   }
}

Update your Manifest

Finally, you’ll need to make the following changes to your Manifest:

  • Request the Internet permission so that your app can connect to Facebook’s servers.
  • Add the application ID string (@string/facebook_app_id) as a meta-data element.
  • Define a FacebookActivity, using com.facebook.FacebookActivity.

At this point you may also want to add support for Chrome Custom Tabs. This step is optional, but it can provide a better experience for any users who prefer to access their Facebook account via Chrome, rather than via the Facebook for Android app.

With Chrome Custom Tabs in place, whenever your app detects that the Facebook for Android app isn’t installed, it’ll launch the Facebook Login dialog as a Chrome Custom Tab, rather than a WebView. This is important as Chrome Custom Tabs share cookies with Chrome, so if the user is logged into Facebook on Chrome then your app will receive their login credentials from Chrome, and they won’t have to input this information manually.

This step is optional, but since it can improve the user experience, I’m also adding it to my Manifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.jessicathornsby.facebooklogin">

   // Add the Internet permission//
   <uses-permission android:name="android.permission.INTERNET"/>

   <application
       android:allowBackup="true"
       android:icon="@mipmap/ic_launcher"
       android:label="@string/app_name"
       android:supportsRtl="true"
       android:theme="@style/AppTheme">

        //Reference your App ID string//
        <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
        <activity android:name=".MainActivity">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
        </activity>

       // Add a Facebook Activity//
       <activity android:name="com.facebook.FacebookActivity"
           android:configChanges=
               "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
           android:label="@string/app_name" />

       // Implement support for Chrome Custom Tabs//
       <activity
           android:name="com.facebook.CustomTabActivity"
           android:exported="true">
           <intent-filter>
               <action android:name="android.intent.action.VIEW" />
               <category android:name="android.intent.category.DEFAULT" />
               <category android:name="android.intent.category.BROWSABLE" />
               <data android:scheme="@string/facebook_app_id" />
          </intent-filter>
       </activity>
   </application>
</manifest>

You can download this project (minus the google-services.json file, App ID and App Secret) from GitHub.

Authenticate with Twitter

In order to implement Twitter Login in your app, you’ll need to complete the following steps:

  • Register your Android app in the Twitter Application Manager.
  • Find your project’s unique Consumer Key and Consumer Secret, and add this information to the Firebase Console and to your Android project.
  • Add Fabric’s Twitter Kit to your Android application.
  • Register your app with the Fabric platform.
  • Implement the Twitter Login flow.

Register your app with the Twitter Application Manager

Start by heading over to the Twitter Application Manager, log in with your Twitter credentials and click ‘Create New App.’ When prompted, enter the following information about your project:

  • Your application name. This is the title that’ll be included in all your app’s user-facing Twitter authorization dialogs.
  • Description. 10 to 200 character describing your application. Again, this information will be included in all user-facing authorization screens.
  • Website. The homepage associated with your application, which will also be included in your app’s authorization screens.
  • Callback URL. This is the URL where Twitter should redirect the user after they’ve completed the Twitter authentication dialog. Leave this field blank for now.

When prompted, read the Developer Agreement, and if you’re happy to proceed then click ‘Create your Twitter Application.’ At this point you’ll be taken to your project’s dedicated Application Management page.

Share your API Key and Consumer Key

The next step is copying the key from your project’s Application Management page, and sharing this information with the Firebase Console and your Android project.

You’ll find your project’s unique Consumer Key (also known as the API Key) and Consumer Secret (also known as the API Secret), by selecting the Application Management’s ‘Keys and Access Tokens’ tab.

Add this information to your Android project, by opening your strings.xml file and creating twitter_consumer_key and twitter_consumer_secret strings:

<resources>
  <string name="twitter_consumer_key" translatable="false">YOURKEY</string>
  <string name="twitter_consumer_secret" translatable="false">YOURKEY</string>
</resources>

Next, head over to the Firebase Console and:

  • Select the project you’re currently working with.
  • Find the ‘Authentication’ card and select its accompanying ‘Get started’ button.
  • Select the ‘Sign-In method’ tab.
  • Choose ‘Twitter’ from the list, and in the subsequent dialog set the slider to the ‘Enable’ position.
  • Copy the ‘API Key’ and the ‘API Secret’ from the Twitter Application Management Console, and paste them into the Firebase Console dialog.
  • The Firebase Console also contains a callback URL that you’ll need to add to your project’s Twitter Application Management page. Copy this URL, and then click ‘Save’ to close the Firebase Console dialog.
  • Flick back to your project’s Twitter Application Management page. Select the ‘Settings’ tab, then paste the URL into the ‘Callback URL’ field and click ‘Update Settings.’

Install Fabric for Android Studio

Fabric is a mobile platform that contains various modular kits, including a Twitter Kit that you can use to integrate Twitter functionality into your Android apps.

Before you can use this kit, you’ll need to install the Fabric plugin, so sign up for a free Fabric account and then complete the following steps in Android Studio:

  • Select ‘Android Studio’ from the toolbar, followed by ‘Preferences…’
  • Select ‘Plugins’ from the left-hand menu.
  • Give the ‘Browse Repositories….’ button a click.
  • Find ‘Fabric for Android Studio,’ then click ‘Install.’
  • Restart Android Studio when prompted.
  • Once Android Studio has restarted, you’ll notice a new ‘Fabric’ button in the toolbar – give this button a click.

  • A new Firebase window will open in your Android Studio window. Select the accompanying ‘Power’ button.
  • Enter the email address and password you used to create your Fabric account, then click the ‘Power’ button again.
  • Select the project you’re currently working with, then click ‘Next.’
  • At this point, you can choose which kits you want to work with; select ‘Twitter.’
  • Select the ‘Twitter: Install’ button.
  • Click ‘I already have a Twitter account’ and enter your Twitter username and password.
  • Fabric will then prompt you for a Twitter/API Key and Twitter/Build Secret. You’ll find this information in the Fabric Dashboard. Copy the API Key and Build Secret into Android Studio, then click ‘Next’ to close this dialog.

Next, open your project-level build.gradle file and add Fabric’s Maven Repository and the io.fabric.tools:gradle buildscript dependency:

buildscript {
   repositories {
       jcenter()
       // Add mavenCentral//
       mavenCentral()
       maven { url 'https://maven.fabric.io/public' }
   }
   dependencies {
       classpath 'com.android.tools.build:gradle:2.2.2'
       classpath 'com.google.gms:google-services:3.0.0'
       // Add io.fabric.tools:gradle//
       classpath 'io.fabric.tools:gradle:1.+'
   }
}

allprojects {
   repositories {
       jcenter()
       // Add mavenCentral//
       maven { url 'https://maven.fabric.io/public' }
       mavenCentral()
   }
}

You’ll also need to add the io.fabric plugin and the Twitter Core Kit to your module-level build.gradle file:

apply plugin: 'com.android.application'

//Add the Fabric plugin//

apply plugin: 'io.fabric'
...
...
...

dependencies {
   compile fileTree(dir: 'libs', include: ['*.jar'])
   androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
       exclude group: 'com.android.support', module: 'support-annotations'
   })
   compile 'com.android.support:appcompat-v7:25.2.0'
   testCompile 'junit:junit:4.12'
   compile 'com.google.firebase:firebase-auth:10.2.0'

   // Add the Twitter Core Kit//
   compile('com.twitter.sdk.android:twitter:2.3.2@aar') {
       transitive = true;
   }
}

Add your Fabric API Key

Fabric assigns you an organization key that you’ll need to add to your project’s Manifest. Head over to the Fabric Dashboard, select your organization and then click the ‘API Key’ text to reveal your key.

Open your project’s Manifest and add this key as a meta-data element inside your <application> tag:

<meta-data
      android:name="io.fabric.ApiKey"
      android:value="YOUR-API-KEY-HERE" />

While you have the Manifest open, you’ll also need to request the Internet permission so that your app can interact with Twitter’s servers:

<uses-permission android:name="android.permission.INTERNET" />

Register your application with Fabric

Once all of this setup is complete, you’ll need to register your app with the Fabric platform, which requires you to build and run your app. Either attach a physical Android device to your development machine or launch an AVD, and then select ‘Run > Run App’ from the Android Studio toolbar.

After a few moments, you should receive an email confirming that a new app has been added to your Fabric account. Open this email and click its ‘View Details’ button, and you’ll be taken to your app’s dedicated page within your Fabric account.

When prompted, read through the ‘Twitter Kit Agreement’ and ‘Developer Agreement’ and confirm that you’re happy to proceed by clicking ‘Get Started.’

Crafting the Twitter Login experience

Similar to the Facebook SDK, the Twitter Core Kit contains a standard Twitter Login button that you can drop into your layout, so open the layout resource file where you want to start the Twitter Login experience, and add the following:

<com.twitter.sdk.android.core.identity.TwitterLoginButton
     android:id="@+id/login_button"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" />

In the accompanying Activity file, you’ll need to create a callback that handles the results of the user’s login attempts, and then attach this callback to your Twitter Login button. Once the user has successfully signed in with Twitter, you’ll also need to exchange the OAuth access token and OAuth secret for a Firebase credential, which you can use to authenticate with Firebase.

Similar to our Facebook app, in the following code I’m also creating a listener (AuthStateListener) that’ll print a message to Android Studio’s Logcat every time the user’s sign-in state changes.

package com.jessicathornsby.twitterlogin;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.content.Intent;
import com.twitter.sdk.android.core.TwitterAuthConfig;
import com.twitter.sdk.android.Twitter;
import io.fabric.sdk.android.Fabric;
import com.twitter.sdk.android.core.Callback;
import com.twitter.sdk.android.core.Result;
import com.twitter.sdk.android.core.TwitterException;
import com.twitter.sdk.android.core.TwitterSession;
import com.twitter.sdk.android.core.identity.TwitterLoginButton;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.TwitterAuthProvider;
import android.support.annotation.NonNull;
public class MainActivity extends Activity {
   private TwitterLoginButton loginButton;
   private static final String TAG = "TwitterLogin";

   // Create a static final TWITTER_KEY and TWITTER_SECRET using the values you retrieved from
   // the Twitter Application Management console. Just make sure you obfuscate this Key and
   // Secret from your source code before releasing your app

   private static final String TWITTER_KEY = "YOUR-TWITTER-KEY";
   private static final String TWITTER_SECRET = "YOUR-TWITTER-SECRET";
   private FirebaseAuth mAuth;
   private FirebaseAuth.AuthStateListener mAuthListener;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      // Initialize Fabric//
      TwitterAuthConfig authConfig = new TwitterAuthConfig(TWITTER_KEY, TWITTER_SECRET);
      Fabric.with(this, new Twitter(authConfig));
      setContentView(R.layout.activity_main);

      // Get a shared instance of the FirebaseAuth object//
      mAuth = FirebaseAuth.getInstance();

      // Set up an AuthStateListener that responds to changes in the user's sign-in state//
      mAuthListener = new FirebaseAuth.AuthStateListener() {
          @Override
          public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
              // Retrieve the user’s account data, using the getCurrentUser method//
              FirebaseUser user = firebaseAuth.getCurrentUser();
              if (user != null) {
                // If the user signs in, then display the following message//
                Log.d(TAG, "onAuthStateChanged" + user.getUid());
              }
           }
       };
       loginButton = (TwitterLoginButton) findViewById(R.id.login_button);

       // Create a callback that’ll handle the results of the login attempts//
       loginButton.setCallback(new Callback<TwitterSession>() {
           @Override
           // If the login is successful...//
           public void success(Result<TwitterSession> result) {
             Log.d(TAG, "twitterLogin" + result);
             handleTwitterSession(result.data);
          }

          @Override
          // If the login attempt fails...//
          public void failure(TwitterException exception) {
            //Do something//
          }
       });
   }

   @Override
   public void onStart() {
       super.onStart();
       mAuth.addAuthStateListener(mAuthListener);
   }

   @Override
   public void onStop() {
       super.onStop();
       if (mAuthListener != null) {
       mAuth.removeAuthStateListener(mAuthListener);
       }
   }

   // Pass the Activity result to the onActivityResult method//
   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       super.onActivityResult(requestCode, resultCode, data);
       loginButton.onActivityResult(requestCode, resultCode, data);
   }

   //Exchange the OAuth access token and OAuth secret for a Firebase credential//
   private void handleTwitterSession(TwitterSession session) {
       Log.d(TAG, "handleTwitterSession:" + session);
 
       AuthCredential credential = TwitterAuthProvider.getCredential(
           session.getAuthToken().token,
           session.getAuthToken().secret);

       //If the call to signInWithCredential succeeds, then get the user’s account data//
       mAuth.signInWithCredential(credential)
           .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
              @Override
              public void onComplete(@NonNull Task<AuthResult> task) {
                Log.d(TAG, "signInWithCredential" + task.isSuccessful());

              }
           });
   }
}

You can find this project (minus the google-services.json file, Twitter Key and Twitter Secret) over at GitHub.

Authentication best practices

After you’ve gone to all the effort of implementing user authentication, you’ll want to ensure as many people take advantage of this feature as possible.

In this section, I’m going to share a few best practices that’ll increase the odds of your users hitting that ‘Sign In’ button.

1. Clearly communicate the benefits

You users should understand the benefits of everything your app asks them to do, but this is particularly important when you’re asking them to hand over personal information such as their Facebook credentials. For the highest conversion rates, you should clearly communicate the benefits of signing into your app, before presenting your users with that ‘Sign In’ button. This could take the form of a promo video demonstrating your app’s features in action, a series of screenshots, or it may even be something as simple as a few bullet points.

2. Give the user a choice

Whenever possible you should give your users the option to use your app without signing in, because if a user isn’t keen on the idea of authenticating with Facebook or Twitter, and you don’t give them the option to use your app anonymously, then you’re probably going to lose them. However, if your app allows anonymous users then there’s still a chance that they may change their mind and sign in at a later date.

If you do allow anonymous users, then make sure they’re full aware of all the features and content they’re missing out on, as this will make them more likely to take the plunge and sign up at a later data.

3. Make signing in as straightforward as possible

As a general rule, the easier the sign in process is, the more users will sign up. We’re already off to a good start by using Facebook and Twitter authentication rather than requiring users to fill in a registration form, but you should still be on the lookout for any opportunities to simplify the login process. For example, if there’s a ‘Registration’ button on your app’s homepage that leads to a ‘Log in with Facebook’ button, then you may want to consider cutting out the middleman and placing that Facebook button directly on your app’s homepage.

If the user does authenticate using an external provider, then you should avoid asking them to enter any additional information on top of this authentication, and in particular never ask the user to create an additional username or password specifically for your app. Both of these actions are likely to leave the user wondering what exactly was the point of authenticating with Facebook or Twitter in the first place, and in the worst case scenario they may even suspect that your app has deliberately tricked them into handing over their social network credentials.

4. Limit the permissions you request at login

When you use external authentication providers, you may need to request some permissions that are specific to that provider, for example Facebook Login supports over 30 Facebook-specific permissions.

However, wherever possible you should avoid making permission requests during authentication, as you don’t want to risk scaring the user off at such a crucial point in the onboarding process. In fact, according to the Facebook Developer docs, apps that request more than four permissions during authentication experience a significant drop in the number of completed logins.

5. Consider including some supporting text

Placing text alongside your login buttons can sometimes give uncertain users that little extra push, convincing them to sign into your app. For social logins like Facebook or Twitter, you may want to include some text stressing how easy it is to sign up (“In a hurry? Sign in with your existing Facebook account and you’ll be up and running in seconds”) or take the opportunity to reassure your users that you won’t post anything to their Facebook or Twitter accounts without their permission.

6. Provide a way to log out

Although this entire tutorial has been geared towards getting users to sign into your app, feeling trapped isn’t exactly a great user experience, so don’t forget to provide your users with a way of signing out. And even though it’s probably the last thing you want your users to do, you should provide them with a way of permanently deleting their account.

8. Don’t forget to test!

You should test your app’s login experience across a range of conditions, including less-than-ideal scenarios such as how your app reacts if a user attempts to sign in with an outdated Facebook password, or if the Internet cuts out halfway through the authentication process. You should also try and get feedback on your app’s onboarding experience, ideally from users who represent your target audience. You can then use their feedback to help improve the login experience.

Wrapping up

In this article we looked at how to implement Facebook and Twitter login, using Firebase Authentication. When exploring the Firebase Console, you may have noticed that Firebase Authentication supports some methods we haven’t looked at – namely GitHub, Google, and email/password authentication.

If you do decide to implement one or more of these methods, then all of the setup (creating a new Firebase project, registering your app with the Firebase Console, and adding the Firebase Authentication library) will be exactly the same, so you’ll be able to use the information at the start of this tutorial to get a head start on adding more sign in methods to your app.
Do you plan on adding user authentication to your Android apps?

Leave a comment