Firebase, Login with Facebook in Jetpack Compose

1. Introduction

In the previous article, we have learn how to login with Google in Jetpack Compose, in this article we will learn how to Login with Facebook, one thing that makes authentication with Facebook particularly difficult on Android is the fact that it always depends on the method on activity result

And throughout this article we will be how to implement authentication with Facebook in an application made entirely with Jetpack Compose

2. Configuration

2.1 Jetpack Compose Installation

To add Jetpack Compose on your project I suggest you follow the steps described in this article Firebase Auth with Jetpack Compose, currently Jetpack Compose is stable but the configuration has not changed, you just have to follow the steps while updating the version to the latest version.

2.2 Facebook Configuration

For your application to support authentication with Facebook, you must have:

  1. A Meta Developer account by clicking here ,
  2. Create an Application in the dashboard of your Meta Developer account
  3. Connect the application created in step 2 to your Android application as shown in the official documentation available here.

The meta developer account you will create will allow you to add other facebook features to your application

Screenshot 2021-12-05 at 18.25.18.png

3. Implementation

For simplicity reasons, we are not going to develop all the architecture of the application because the objective is simply to show how to make the authentication with Firebase with Jetpack Compose, and in this article we will only focus on Firebase Auth with Facebook Login

3.1 Using Facebook LoginButton

To add a login button with Facebook, we will create a composable whose structure looks like the following code snippet, note that the LoginButton came with the Facebook Android SDK.

@Composable
fun CustomFacebookButton(
  modifier: Modifier = Modifier,
  enabled: Boolean = true,
  onSuccess: (LoginResult) -> Unit,
  onCancel: () -> Unit,
  onError: (FacebookException?) -> Unit,
) {
    // Button Logic
}

As the LoginButton class is not a Jetpack Compose component, we need to use the AndroidView composable to be able to use it in Jetpack Compose as shown in the following code.

@Composable
fun CustomFacebookButton(
  modifier: Modifier = Modifier,
  enabled: Boolean = true,
  onSuccess: (LoginResult) -> Unit,
  onCancel: () -> Unit,
  onError: (FacebookException?) -> Unit,
) {

  val callbackManager = FacebookUtil.callbackManager
  val loginText = stringResource(R.string.txt_connect_with_facebook)
  AndroidView(
    modifier = modifier.fillMaxWidth().height(50.dp),
    factory = ::LoginButton,
    update = { button ->
      button.setLoginText(loginText)
      button.setPermissions("email")
      button.isEnabled = enabled

      button.registerCallback(callbackManager, object : FacebookCallback<LoginResult> {
        override fun onSuccess(result: LoginResult) {
          onSuccess(result)
          Timber.e("Login : ${result.accessToken}")
        }

        override fun onCancel() {
          onCancel()
          Timber.e("Login : On Cancel")
        }

        override fun onError(error: FacebookException?) {
          onError(error)
          Timber.e("Login : ${error?.localizedMessage}")
        }
      })
    }
  )
}

As you have probably seen, the Composable AndroidView has two important parameters, the first is factory a lambda to use the creation of the component, the second parameter is update to use to modify the component previously created

In our case, we passed the LoginButton reference to the factory parameter, so we don't have to create an xml file containing only the button

And in the update lambda, we just made some configuration on the button.

3.1.1 Callback Manager

For the authentication to succeed, it is necessary to attach to the button a callback possessing a certain number of methods which will be called according to the authentication failed, cancelled or succeeded

If you look closely at the code at the very beginning, you will see a piece of code that looks like this, FacebookUtil.callbackManager

val callbackManager = FacebookUtil.callbackManager

FacebookUtil is a singleton, a Kotlin Object that I've create in order to store the instance of the callback manager,

You will see the purpose of this technique very soon and the code of the FacebookUtil object looks like this.

object FacebookUtil {
  val callbackManager by lazy {
    CallbackManager.Factory.create()
  }
}

At this moment, if you have done the configurations well and you add the composable we just created to your interface, you will see a Facebook button appear

And if you click on the button, you will be redirected to a Facebook window where you can type in your facebook ID to connect

Once logged in, you will be automatically redirected to your application, where one of the 3 callbacks will be called depending on whether the authentication was successful, failed or cancelled

But if you try to do this actually you will find that no callback will be called, why, well we will answer this question in the next session.

3.1.2 Finalize the authentication

So that Facebook can return to your application the information related to the connection, ie if the connection was successful or not, you must redefine the method onActivityResult of your activity then call the method CallbackManager.onActivityResult, it's true that the method on activityResult is depreciated but unfortunately the Android sdk of facebook do not yet take into account this update so for the authentication to work it is necessary to put this piece of code in your activity

class MainActivity : ComponentActivity() {

  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    FacebookUtil.callbackManager.onActivityResult(requestCode, resultCode, data)
    super.onActivityResult(requestCode, resultCode, data)
  }

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      MyApplicationTheme {
        RootScreen()
      }
    }
  }
}

In this code snippet, I hope you'll notice that I used FacebookUtil.callbackManager again, the callbackManger used must be the same instance as the one we used to register the callback on the button button.registerCallback(callbackManager, ...)

That's why I made sure to put the CallbackManager in a Kotlin object

4. Summary

Jetpack Compose is already stable, that means you can use it in production in all security, and the majority of applications currently have at least a means of authentication and through this article I hope you will take more taste to use Jetpack Compose in your applications or your future application

Feel free to leave me a comment if you have a question in the comment section or on my twitter

5. Read More

Did you find this article valuable?

Support Eric Ampire by becoming a sponsor. Any amount is appreciated!