It’s probably common knowledge right now that doing a standard email-password authentication in Firebase is piss easy. The same can’t be said about using it’s various providers, Facebook, Twitter, Google, Play Games, Github, etc. and that’s because each one requires its own unique set up which isn’t always so straightforward.
Today, I’m going to focus on the first 3 and what I believe to be the most prominent ones: Facebook, Twitter, and Google.
Import the Dependencies
On top of connecting your app to Firebase, add these dependencies to your app/build.gradle file. The last 3 correspond to Facebook, Twitter, and Google login respectively.
implementation 'com.google.firebase:firebase-auth:16.1.0' implementation 'com.facebook.android:facebook-android-sdk:[4,5)' implementation('com.twitter.sdk.android:twitter:3.3.0@aar') { transitive = true } implementation 'com.google.android.gms:play-services-auth:16.0.1'
If your Twitter dependency is causing an error (Error: Invoke-customs are only supported blah blah blah) then add this as well (courtesy of StackOverflow)
android { .... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
Before we begin
Get an instance of FirebaseAuth as a global variable. You’ll need it.
val auth = FirebaseAuth.getInstance()
Don’t forget to declare a button that lets you sign out of Firebase Auth if you haven’t already.
auth.signOut()
And to get your user data after signing in with any of these methods, run this code in your OnStart method.
override fun onStart() { super.onStart() val user = auth.currentUser updateUI(user) }
For Facebook and Twitter login, you’ll have to initialize their SDKs when your app starts. If you don’t know how to do this, make a class that extends Application and override onCreate to do add your initialization code later. Then in your Manifest, add the android:name attribute to your <Application> pointing to the Application class you just created.
This tutorial assumes you know the basics of Firebase Authentication and as such, knowing how to tailor the result of signInWithCredential() to your app’s needs. If not, check out my Introduction to Firebase Authentication.
To start, head to the Facebook Developers site and create a new app there. In the dashboard of your newly created app, click Facebook Login and follow the quickstart.
It’s all pretty straightforward until Step 4 where you have to generate a keyhash using a tool called Keytool. Fortunately for you, this tool is located in your JDK/bin folder.
You’ll also need the OpenSSL library from the Google Code Archive. Once you have both, run this command replacing the OpenSSL Paths and your USERNAME to generate the hash.
keytool -exportcert -alias androiddebugkey -keystore "C:\Users\USERNAME\.android\debug.keystore" | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" sha1 -binary | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" base64
Then in Step 7, you’ll have to initialize the Facebook SDK once when your app is created. (See Before we Begin if you’re stuck).
Once you’re done with the quickstart, go to the Settings of the your Facebook App, there you’ll find your App ID and App Secret. Go to the Firebase Console > Authentication > Sign-In Method, enable Facebook and copy in your App ID and Secret. Below where you pasted the Secret, you’ll see an OAuth Redirect URI. Copy that, then go to the Facebook Login > Settings, and paste it in the OAuth Redirect URIs section there.
Before where you register your callback, change the value of setReadPermissions to “email”, “public_profile” .
And using the Access Token from the Success method of the Facebook Callback, get a Facebook Auth Credential and use it to sign in to Firebase Auth.
private fun initFacebookLogin() { facebookLogInButton.setReadPermissions("email", "public_profile") // If you are using in a fragment, call loginButton.setFragment(this); // Callback registration facebookLogInButton.setReadPermissions() facebookLogInButton.registerCallback(callbackManager, object : FacebookCallback<LoginResult> { override fun onSuccess(loginResult: LoginResult) { handleFacebookAccessToken(loginResult.accessToken) } override fun onCancel() { } override fun onError(exception: FacebookException) { } }) }
To start, go to Twitter Developers and create an application there. As you go through the app creation process on the Twitter Developer site, you’ll need a Callback URL to enable Twitter Login which you’ll find in Firebase Console > Authentication > Sign-In Method > Twitter. After creating the app, you’ll find the API Key and Secret which you should paste in the Firebase Console above where you found the Callback URL.
Add your API Key and Secret to your app as well as string resources and use them to initialize the Twitter SDK when you start your app (See Before we Begin if you’re stuck).
val config = TwitterConfig.Builder(this) .logger(DefaultLogger(Log.DEBUG)) .twitterAuthConfig(TwitterAuthConfig(getString(R.string.twitter_api_key), getString(R.string.twitter_api_secret))) .debug(true) .build() Twitter.initialize(config)
Next, add the TwitterLoginButton to your layout.
<com.twitter.sdk.android.core.identity.TwitterLoginButton android:id="@+id/twitterLogInButton" android:layout_width="wrap_content" android:layout_height="wrap_content" />
Then add a callback to your button
twitterLogInButton.callback = object : Callback<TwitterSession>() { override fun success(result: Result<TwitterSession>) { // Do something with result, which provides a TwitterSession for making API calls } override fun failure(exception: TwitterException) { // Do something on failure } }
Add this to your OnActivityResult
twitterLogInButton.onActivityResult(requestCode, resultCode, data)
Now once authenticated with Twitter, you can get an OAuth Access Token and OAuth Secret
val session = TwitterCore.getInstance().sessionManager.activeSession val authToken = session.authToken val token = authToken.token val secret = authToken.secret
Use this to create a Firebase credential which you can then use to sign in
val credential = TwitterAuthProvider.getCredential( session.authToken.token, session.authToken.secret) auth.signInWithCredential(credential)
First, make sure Google-Sign In is enabled in Firebase Console > Authentication > Sign-In Methods. Then follow Google’s page on Integrating Google-Sign In into your Android App.
When you’re done, go back to where you build the GoogleSignInOptions and replace it with this.
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build()
Replace the ID Token with your own server’s OAuth 2.0 client ID which you can get on the Google API Console. It will be the one of type Web Application.
Then in OnActivityResult where you respond to the Google-Sign In request code, you’ll have access to the account which gives you the credentials to authenticate with Firebase.
if (requestCode == RC_GOOGLE_SIGN_IN) { val task = GoogleSignIn.getSignedInAccountFromIntent(data) val account = task.getResult(ApiException::class.java) val credential = GoogleAuthProvider.getCredential(account.idToken, null) auth.signInWithCredential(credential) }
Extending with FirebaseUI
It’s worth knowing you can omit much of the code here by using Firebase UI to sign in with these providers. You can do so by importing these dependencies:
implementation 'com.firebaseui:firebase-ui-auth:4.3.1' implementation 'com.facebook.android:facebook-android-sdk:4.41.0' implementation 'com.twitter.sdk.android:twitter-core:3.3.0'
Then follow my tutorial on Authenticating with FirebaseUI, including the providers you want.
For Facebook and Twitter, you’d still have to set up your app in their respective developer sites and get these resources to put in your strings.xml
<resources> <!-- Facebook application ID and custom URL scheme (app ID prefixed by 'fb'). --> <string name="facebook_application_id" translatable="false">YOUR_APP_ID</string> <string name="facebook_login_protocol_scheme" translatable="false">fbYOUR_APP_ID</string> <!-- Twitter consumer key and secret --> <string name="twitter_consumer_key" translatable="false">YOUR_CONSUMER_KEY</string> <string name="twitter_consumer_secret" translatable="false">YOUR_CONSUMER_SECRET</string> </resources>
Get the Source Code
If you want to look at the complete code, here’s a link to the source code on Github.