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
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...
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")
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...
}
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)
}
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
}
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()
}
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)
}
}
}
-
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 likesuccess
andfailure
, 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")
}
}
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{
it starts a try block and gets the result from the task in
val account=task.getResult(ApiException::class.java)
account
variable.
account?.idToken?.let {idToken->
GoogleSignInManager.authenticateWithFirebase(
idToken,
onSuccess = {
onSignInSuccess(it)
},
onFailure = {
signInResult="Sign in failed: ${it?.message}"
onSignInFailure(signInResult?:"unknown result")
}
)
}
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")
}
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.
Top comments (0)