DEV Community

Cover image for Google Sign-in using Firebase. A beginner Guide.
Harsh Lade
Harsh Lade

Posted on

1

Google Sign-in using Firebase. A beginner Guide.

Introduction

In this article, we will see how we can add features of Google sign in in our app using Firebase.

Prerequisits

  • Firebase project setup and connect to firebase.
  • Firebase authentication enabled in Project.

You can see them in the previous article.


Step 1: Adding SHA-1 Certificate.

SHA stands for Secure Hash Algorithm. We need to add this certificate in our Firebase project.

1. Finding SHA-1 Certificate

To find SHA-1 certificate, first open your android studio -> terminal, then run the following command on terminal.

./gradlew signingReport
Enter fullscreen mode Exit fullscreen mode

Then you will see something like this:

Store: C:\Users\YourUsername\.android\debug.keystore
Alias: AndroidDebugKey
MD5:  A1:B2:C3:D4:E5:F6:G7:H8:I9:J0:K1:L2:M3:N4:O5:P6
SHA-1: 11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33
SHA-256: XX:YY:ZZ...
Enter fullscreen mode Exit fullscreen mode

Copy the SHA-1 id from here.

2. Adding SHA-1 to Firebase.

  • Open Firebase console -> select your app.
  • Go to Project settings.
  • Scroll down to your apps -> select your android app.
  • Click on add fingerprint.
  • Paste SHA-1 key and save it.

3. Adding new google-service.json.

Copy your google-service.json file from firebase.
Now open your android studio and replace the old google-service.json with the new one.

Open the googl-service.json, under client -> outh_Client -> copy the client_id, it is your webClintId save this id we will need in future.


Step 2 (Adding Google Sign in):

Google sign in allows user to sign in using their account.

1. Set up

Open Firebase console -> Authentication -> Sign in Method -> enable Google.
Note down the web client Id.

2. Add Dependencies.

Open your build.gradle file and add the following dependcies.

    //Add the following line.
    implementation ("com.google.firebase:firebase-auth:22.1.1")
    implementation ("com.google.android.gms:play-services-auth:20.7.0")
Enter fullscreen mode Exit fullscreen mode

Step 3 (Creating a Google Sign-in Manager)

We will wrap up all the back-end code into the object GoogleSignInManager, we will add all the functionalities inside this object. It will make a singleton, means it will be same through the whole app. It is a type of pattern.

  • This ensures that we don't create multiple googleSignInUsers inside our app.

1. Initialize Google Sign-in client.

object GoogleSignInManager {
    private lateinit var googleSignInClient: GoogleSignInClient
    //other code...
}
Enter fullscreen mode Exit fullscreen mode

This will create a variable that we will initialize later. lateinit var is used to define a variable which gets initialize later in future.

2. Set up Google Sign-in options.

Now we will add Google sign-in options in our GoogleSignInManager. We will make a function initialize.

fun initialize(context: Context) {
        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken("556979410722-v79hg8m78s8tbqt6hqofdhe9a4k1uml7.apps.googleusercontent.com")//replace with `webClientId`(you can check it in google-service.json).
            .requestEmail()
            .build()

        googleSignInClient = GoogleSignIn.getClient(context, gso)
    }
Enter fullscreen mode Exit fullscreen mode

Here, we create GoogleSignInOption, it tells that which type of sign in we want (eg. email, phone).

  • .requestIdToken(webClientId) requests an id token for Firebase Authentication.
  • .requestEmail() requests Email of the user.
  • GoogleSignIn.getClient() set ups a client with the given option(gso).

3. Adding Sign in intent.

We will create a function that returns the intent, which will help us launch Google sign-in.

fun getSignInIntent(): Intent {
        return googleSignInClient.signInIntent
    }
Enter fullscreen mode Exit fullscreen mode

This will return an intent that launches Google sign-in UI. It is used to start the Google sign-in process.

4. Creating Sign-out function.

This sign-out function will help the user to sign out through the account.

    fun signOut(){
        googleSignInClient.signOut()
    }
Enter fullscreen mode Exit fullscreen mode

4. Authenticate with Firebase.

To authenticate the user with Firebase, we will make a function that authenticates the user.

fun authenticateWithFirebase(
        idToken: String,
        onSuccess: (FirebaseUser?) -> Unit,
        onFailure: (Exception?) -> Unit
    ) {
        val credential = GoogleAuthProvider.getCredential(idToken, null)
        FirebaseAuth.getInstance().signInWithCredential(credential)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    onSuccess(FirebaseAuth.getInstance().currentUser)
                } else {
                    onFailure(task.exception)
                }
            }
    }
Enter fullscreen mode Exit fullscreen mode
  • val credential =GoogleAuthProvider.getCredential(idToken,null) converts the idToken to Firebase credentials.
  • FirebaseAuth.getInstance().signInWithCredential(credential) tells the Firebase to sign in with the Google's Credentials.
  • addOnCompleteListener is used to handle the result case like success and failure, so that we can perform desired task in each situation.

Step 4 (UI & Launcher).

Now, we are done with almost everything but the UI. For testing purposes, we can add only a simple button inside the UI. Also, we will create a launcher, which get called when the user clicks on the Sign in button.

1. Launcher

val launcher= rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult()
    ) {result->
        val task=GoogleSignIn.getSignedInAccountFromIntent(result.data)
        try{
            val account=task.getResult(ApiException::class.java)
            account?.idToken?.let {idToken->
                GoogleSignInManager.authenticateWithFirebase(
                    idToken,
                    onSuccess = {
                        onSignInSuccess(it)
                    },
                    onFailure = {
                        signInResult="Sign in failed: ${it?.message}"

                        onSignInFailure(signInResult?:"unknown result")
                    }

                )

            }
        }
        catch (e:ApiException){
            signInResult="Sign in failed: ${e.message}"

            onSignInFailure(signInResult?:"unknown result")
        }


    }
Enter fullscreen mode Exit fullscreen mode
  • rememberLauncherActivityForResult() is a jetpack compose way to handle the activity result (i.e., getting the result from other activities, Google sign-in in this case.

  • ActivityResultContracts.StartActivityForResult expects an intent and returns a result after the activity (in this case it will return the user's detail after sign-in).

  • val task=GoogleSignIn.getSignedInAccountFromIntent(result.data) returns the result from intent, which we can then retrieve using .getResult(ApiExcetption::class.java).

  • try{
    val account=task.getResult(ApiException::class.java)
    it starts a try block and gets the result from the task in account variable.

 account?.idToken?.let {idToken->
                GoogleSignInManager.authenticateWithFirebase(
                    idToken,
                    onSuccess = {
                        onSignInSuccess(it)
                    },
                    onFailure = {
                        signInResult="Sign in failed: ${it?.message}"
                        onSignInFailure(signInResult?:"unknown result")
                    }
                )
            }
Enter fullscreen mode Exit fullscreen mode

Above code will check if account and idToken is not null then it will send the idToken to our authenticateWithFirebase function inside the GoogleSignInManager singleton object and authenticate the user with firebase, also handles the success and failure cases.

  • Lastly, Catch block handles the exception.

2. Button Component.

Button(onClick = {
            val signInIntent = GoogleSignInManager.getSignInIntent()
            launcher.launch(signInIntent)
        }) {
            Text("Sign in with Google")
        }
Enter fullscreen mode Exit fullscreen mode

When any user clicks on the button, we will get Intent and will launch the launcher.

.getSignInIntent() returns an intent that we will pass into the launcher to Launch the Google sign-in UI.


Conclusion

In this article, we have discussed how we can implement the Google sign-in feature in our app using Firebase Authentication. First, we added the SHA-1 certificate of our app in Firebase, then we added the necessary dependencies to our project. After that, we made a singleton object GoogleSignInManager in which we said all the essential methods for authentication, initialization, getIntent, and sign-out. Then we implemented a launcher that launches the Google sign-in UI and get the result.
Please, give your feedback. Also, you can ask your doubts. Next, we will discuss Firestore so stay tuned.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

Sentry growth stunted Image

If you are wasting time trying to track down the cause of a crash, it’s time for a better solution. Get your crash rates to zero (or close to zero as possible) with less time and effort.

Try Sentry for more visibility into crashes, better workflow tools, and customizable alerts and reporting.

Switch Tools