Firebase Authentication is a powerful tool that simplifies user authentication in mobile applications. It provides various backend services, allowing developers to authenticate users using common identity providers like Google, Facebook, and more. This is particularly important in applications where user identity is crucial for personalized experiences, data security, and interaction.
In this tutorial, we will focus on integrating Google Sign-In with Firebase Authentication within an Android application using Kotlin. We'll explore the necessary steps to set up everything from the Firebase console to the code that handles user login. By the end of this guide, you will have a fully functional application that can authenticate users via their Google accounts.
Why Use Firebase Authentication?
- Simplicity: Firebase provides a straightforward API that is easy to integrate.
- Security: It manages user data and authentication securely, reducing the risk of vulnerabilities.
- Multiple Providers: Easily switch between different authentication providers without altering your existing logic.
Steps to Set Up Firebase for Your Android App
Step 1: Create a Firebase Project
- Go to the Firebase Console.
- Click on "Go to Console".
- Click on "Add Project" and fill in the required details.
- Once your project is created, click "Continue".
- In your Firebase project, click on "Add App" and select Android.
- Provide your app's package name and other required information.
- Click on "Register App".
- Download the
google-services.jsonfile and place it in your app'sapp/directory.
Step 2: Register Your Android App
Step 3: Add Firebase SDK Dependencies
Open your build.gradle files and add the following dependencies.
Project-level build.gradle:
buildscript {
dependencies {
// Other dependencies
classpath 'com.google.gms:google-services:4.3.10'
}
}
Module-level build.gradle:
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
dependencies {
implementation 'com.google.firebase:firebase-auth-ktx:21.0.1'
implementation 'com.google.android.gms:play-services-auth:20.1.0'
// Other dependencies
}
Step 4: Enable Google Sign-In in Firebase
- In the Firebase Console, navigate to Authentication.
- Click on the "Sign-in Method" tab.
- Enable Google as a sign-in provider and save the changes.
Code Implementation
Now that we have set up Firebase, let’s implement Google Sign-In in our Android application using Kotlin.
Step 1: Layout XML for MainActivity
Create a layout file named activity_main.xml with a Google Sign-In button.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/instructionText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sign in with Google"
android:layout_centerInParent="true"
android:textSize="18sp" />
<com.google.android.gms.common.SignInButton
android:id="@+id/googleSignInButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/instructionText"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"/>
</RelativeLayout>
Step 2: Create MainActivity
Now, create the MainActivity.kt file where we will implement the Google Sign-In logic.
package com.example.firebasegooglelogin
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.auth.api.Auth
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.tasks.Task
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.GoogleAuthProvider
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private lateinit var googleApiClient: GoogleApiClient
private lateinit var firebaseAuth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
firebaseAuth = FirebaseAuth.getInstance()
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleApiClient = GoogleApiClient.Builder(this)
.enableAutoManage(this) { connectionResult ->
Log.w("MainActivity", "Google sign in failed: ${connectionResult.errorMessage}")
}
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build()
googleSignInButton.setOnClickListener {
signIn()
}
}
private fun signIn() {
val signInIntent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient)
startActivityForResult(signInIntent, RC_SIGN_IN)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_SIGN_IN) {
val result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
handleSignInResult(result)
}
}
private fun handleSignInResult(result: com.google.android.gms.auth.api.signin.GoogleSignInResult) {
if (result.isSuccess) {
val account: GoogleSignInAccount? = result.signInAccount
account?.let {
firebaseAuthWithGoogle(it)
}
} else {
Log.e("MainActivity", "Google Sign In failed.")
Toast.makeText(this, "Sign In Failed", Toast.LENGTH_SHORT).show()
}
}
private fun firebaseAuthWithGoogle(account: GoogleSignInAccount) {
val credential = GoogleAuthProvider.getCredential(account.idToken, null)
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this) { task: Task<Void> ->
if (task.isSuccessful) {
Log.d("MainActivity", "signInWithCredential:success")
Toast.makeText(this, "Sign In Successful", Toast.LENGTH_SHORT).show()
// Navigate to ProfileActivity
} else {
Log.w("MainActivity", "signInWithCredential:failure", task.exception)
Toast.makeText(this, "Authentication Failed", Toast.LENGTH_SHORT).show()
}
}
}
companion object {
private const val RC_SIGN_IN = 9001
}
}
Step 3: Create ProfileActivity
Once signed in, you might want to show user details. Here’s a simple ProfileActivity.kt.
package com.example.firebasegooglelogin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import kotlinx.android.synthetic.main.activity_profile.*
class ProfileActivity : AppCompatActivity() {
private lateinit var firebaseAuth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile)
firebaseAuth = FirebaseAuth.getInstance()
val user = firebaseAuth.currentUser
user?.let {
userNameTextView.text = it.displayName
userEmailTextView.text = it.email
}
logoutButton.setOnClickListener {
firebaseAuth.signOut()
// Navigate back to MainActivity
}
}
}
Step 4: Layout XML for ProfileActivity
Create a layout file named activity_profile.xml.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/userNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"/>
<TextView
android:id="@+id/userEmailTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"/>
<Button
android:id="@+id/logoutButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Logout"/>
</LinearLayout>
Common Mistakes
Here are some typical mistakes that beginners might encounter when implementing Firebase Authentication:
- Missing Internet Permission: Ensure that you have the following permission in your
AndroidManifest.xml: - Incorrect SHA-1 Key: If you encounter issues signing in, make sure that the SHA-1 key of your app is correctly set in the Firebase console.
- Not Adding the
google-services.json: Ensure that this file is correctly placed in theapp/directory. - Use Kotlin Extensions: Take advantage of Kotlin's extension functions to simplify your code.
- Error Handling: Always handle errors gracefully and provide feedback to users.
- User Experience: Show loading indicators during authentication processes to improve user experience.
<uses-permission android:name="android.permission.INTERNET" />
Best Practices
Practice Exercises
- Create a Logout Functionality: Expand your
ProfileActivityto implement a complete logout functionality. - Display User Profile Picture: Use an ImageView to show the user's profile picture from Google.
- Add More Sign-In Options: Explore integrating other sign-in methods like Facebook or Twitter using Firebase.
By following these steps and implementing the provided code, you will have a solid foundation for implementing Google Sign-In using Firebase Authentication in your Android applications. Happy coding!