Building a Social Media App (Part 1)
Are you interested in building your own social media app, complete with real-time database functionality? Look no further! In this blog post, I'll walk you through the process of creating a fully functional social media app using Kotlin and Firebase's real-time database. Whether you're a beginner or an experienced developer, I've got you covered - this step-by-step guide will take you from start to finish, providing you with all the code and resources you need to create your own custom social media app. So if you're ready to dive in and start building, tune in to some music and let's get started!🥳
Creating a new project✅
So the very first step is to create a new project in Android Studio.
So I'll be naming the project Social Hive, you can name it anything you want. Also, we'll be using Kotlin in this project.
Create a basic layout for your app✅
Design a simple layout for your activity_main.xml
, this will show a Sign-Up interface.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/welcomeTv"
style="@style/TextAppearance.Material3.HeadlineMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:fontFamily="@font/cantata_one"
android:text="@string/welcome"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/nameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
app:boxCornerRadiusTopEnd="10dp"
app:boxCornerRadiusTopStart="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/welcomeTv">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/nameEt"
style="@style/ThemeOverlay.Material3.TextInputEditText.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/enter_your_name" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/emailLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="16dp"
app:boxCornerRadiusTopEnd="10dp"
app:boxCornerRadiusTopStart="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/nameLayout">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/emailEt"
style="@style/ThemeOverlay.Material3.TextInputEditText.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/enter_your_email" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/passwordLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="16dp"
app:boxCornerRadiusTopEnd="10dp"
app:boxCornerRadiusTopStart="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/emailLayout"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/passwordEt"
style="@style/ThemeOverlay.Material3.TextInputEditText.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/enter_password" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/rePasswordLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="16dp"
app:boxCornerRadiusTopEnd="10dp"
app:boxCornerRadiusTopStart="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/passwordLayout"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/rePasswordEt"
style="@style/ThemeOverlay.Material3.TextInputEditText.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/re_enter_your_password" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/createAccBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:text="@string/create_account"
app:cornerRadius="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rePasswordLayout" />
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/createAccBtn">
<View
android:id="@+id/view"
android:layout_width="100dp"
android:layout_height="1dp"
android:layout_gravity="center"
android:layout_marginEnd="-10dp"
android:layout_weight="1"
android:background="@android:color/darker_gray" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/or_login_using"
android:textAlignment="center" />
<View
android:id="@+id/view2"
android:layout_width="100dp"
android:layout_height="1dp"
android:layout_gravity="center"
android:layout_marginStart="-10dp"
android:layout_weight="1"
android:background="@android:color/darker_gray" />
</LinearLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/googleBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="@string/google"
android:textColor="@color/white"
app:backgroundTint="@android:color/transparent"
app:cornerRadius="10dp"
app:icon="@drawable/google_icon"
app:iconGravity="textStart"
app:iconSize="30dp"
app:iconTint="@null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout"
app:strokeColor="@android:color/darker_gray"
app:strokeWidth="1dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/googleBtn">
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/already_have_an_account"
android:textAlignment="textEnd"
android:textSize="16sp" />
<TextView
android:id="@+id/signInTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_weight="1"
android:text="@string/sign_in"
android:textColor="#5462BF"
android:textSize="16sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Enable View Binding✅
Enable view binding by adding the below code to your build.gradle(app)
file -
buildFeatures{
viewBinding = true
}
Also, make the necessary changes in the MainActivity.kt
file
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
Add Firebase to your project✅
Go to Tools>Firebase
Then navigate to Authentication
Click on Authenticate using Google
Then, the Firebase assistant will show you some steps. Click on Connect to Firebase.
It will redirect you to the Firebase Console.
Then click on Add Project
Click Continue
Continue again, then you'll get to the 3rd step, here you can select your Google account and Create Project.
Then it will ask you to Connect your app to Firebase, and click Continue.
Now, your project is connected to Firebase.
Go back to Android Studio, now you're on the 2nd step click on Add the firebase Authentication SDK to your app.
It will prompt you to accept changes, click Accept Changes.
It will add all the dependencies required for the authentication and firebase.
Now you need to add SHA-1 keys to your app in the Firebase Console.
Then go to the gear icon>Project settings scroll down and you will see an option for downloading the
google-services.json
file. Download that.-
You need to add this file now in your app. You can search in android studio by Double Shift and search for
google-services.json
and then replace the contents of the file with the one you downloaded. Go back to your Firebase console>Build>Authentication.
Under Sign-in methods, enable email/password.
Add new provider>Google, add support email id and enable this.
Yayyyyy! now we are all set for implementing the authentication😄
Adding code for Email Authentication✅
So, I have explained all the code in the comments
package com.example.socialhive
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import com.example.socialhive.databinding.ActivityMainBinding
import com.google.firebase.auth.FirebaseAuth
class MainActivity : AppCompatActivity() {
// here we'll instantiate all variables
private lateinit var binding: ActivityMainBinding
// creating var to initialize Firebase auth
private lateinit var auth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// initializing the auth variable
auth = FirebaseAuth.getInstance()
// adding on click listener to create account button
binding.createAccBtn.setOnClickListener {
// making separate method for creating new account for user
logInUserWithEmail()
}
}
private fun logInUserWithEmail() {
// getting the text from all the edit text fields in strings
val name = binding.nameEt.text.toString()
val email = binding.emailEt.text.toString()
val password = binding.passwordEt.text.toString()
val rePassword = binding.rePasswordEt.text.toString()
// creating a var which will tell you if all the input fields are valid
var isValid = false
if (!isValid) { // checking if all are valid, if not showing the error message
if (name.isEmpty()) {
binding.nameEt.error = "Please enter your name"
binding.nameEt.requestFocus()
}
if (email.isEmpty()) {
binding.emailEt.error = "Please enter your email"
binding.emailEt.requestFocus()
}
if (password.isEmpty()) {
binding.passwordEt.error = "Please enter your password"
binding.passwordEt.requestFocus()
}
if (name.isEmpty()) {
binding.rePasswordEt.error = "Please enter your password again"
binding.rePasswordEt.requestFocus()
}
if (password != rePassword) {
binding.rePasswordEt.error = "Passwords don't match"
binding.rePasswordEt.requestFocus()
}
isValid = true
}
if (isValid) { // if isValid true, then creating a new user
auth.createUserWithEmailAndPassword(email, password).addOnCompleteListener {
if (it.isSuccessful) {
// storing the current user in user var
val user = auth.currentUser
// now signing in the user
auth.signInWithEmailAndPassword(email, password).addOnCompleteListener {
if (it.isSuccessful) {
// adding intent if user is successfully created then pass the user to HomeActivity
val intent = Intent(this, HomeActivity::class.java)
// passing user's info through intent, so we can use that later
intent.putExtra("email", user?.email)
intent.putExtra("name", user?.displayName)
intent.putExtra("profile", user?.photoUrl)
startActivity(intent)
} else {
Toast.makeText(
this,
"Login error : ${it.exception.toString()}",
Toast.LENGTH_SHORT
)
.show()
}
}
} else {
Toast.makeText(
this,
"Sign-up error : ${it.exception.toString()}",
Toast.LENGTH_SHORT
)
.show()
}
}
}
}
}
And yes you need to make a new activity, HomeActivity
by right-clicking on app>new>activity>Empty Activity.
After that if you run your app, add all the credentials and then click on Create Account button, it will navigate you to the HomeActivity.
Also, you can see the user's details who logged in to the app in Firebase Console.
Hurrayyyyy! The first milestone is completed🥳
You can add another activity, Login Activity which will log in the users who have already created the account.
Now we will further see how to create a user's new account by Google.
Adding code for Google Authentication✅
Firstly we will create a new variable
// creating var to instantiate google sign in client
private lateinit var googleSignInClient : GoogleSignInClient
Then we will add this code to the onCreate() method -
// initializing the auth variable
auth = FirebaseAuth.getInstance()
// we are creating a variable for Google Sign in options
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id)) // -> it may show error on default_web_client_id, it will disappear automatically
.requestEmail()
.build()
// initializing google sign in client
googleSignInClient = GoogleSignIn.getClient(this, gso)
// adding on click listener to the google button
binding.googleBtn.setOnClickListener {
// also creating a separate method for google sign in
googleSignIn()
}
Then we will create the googleSignIn() method and all other necessary methods outside the onCreate() method
private fun googleSignIn() {
// creating a signInIntent which we can use later while signingIn
val signInIntent = googleSignInClient.signInIntent
launcher.launch(signInIntent)
}
// this will get signed in account from the intent and handle the task in between
private val launcher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val task = GoogleSignIn.getSignedInAccountFromIntent(result.data)
handleResults(task)
}
}
// this method will handle the task after the sign in with user is completed
private fun handleResults(task: Task<GoogleSignInAccount>) {
if (task.isSuccessful) {
val account: GoogleSignInAccount? = task.result
if (account!=null){
updateUI(account)
}
} else {
Toast.makeText(this, task.exception.toString(), Toast.LENGTH_SHORT).show()
}
}
// this will update the UI according to the tasks
private fun updateUI(account: GoogleSignInAccount) {
val credential = GoogleAuthProvider.getCredential(account.idToken, null)
auth.signInWithCredential(credential).addOnCompleteListener {
if (it.isSuccessful) {
val intent: Intent = Intent(this, HomeActivity::class.java)
intent.putExtra("gmail", account.email)
intent.putExtra("gName", account.displayName)
intent.putExtra("gProfile", account.photoUrl)
startActivity(intent)
} else {
Toast.makeText(this, it.exception.toString(), Toast.LENGTH_LONG).show()
}
}
}
After that, you can make some changes in the HomeActivity.kt
package com.example.socialhive
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.socialhive.databinding.ActivityHomeBinding
import com.google.firebase.auth.FirebaseAuth
class HomeActivity : AppCompatActivity() {
// again instantiate these vars
private lateinit var auth: FirebaseAuth
private lateinit var binding: ActivityHomeBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(binding.root)
// initializing auth
auth = FirebaseAuth.getInstance()
// getting data from the intents passed
val email = intent.getStringExtra("email")
val name = intent.getStringExtra("name")
val profile = intent.getStringExtra("profile")
val gName = intent.getStringExtra("gName")
val gmail = intent.getStringExtra("gmail")
val gProfile = intent.getStringExtra("gProfile")
// changing the text to show the name of user got from the google account
binding.textView.text = gName
}
}
Also, I have added a textview in the activity_home.xml
to show the user's name -
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
So, another milestone is achieved! Congrats, if you have come this far🥳
In the next part of this blog, we will use the Real-Time database to do CRUD operations on the posts.
And if you want the whole code, you can check this code out on my GitHub.
Subscribe to my newsletter
Read articles from Deeksha Agarwal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Deeksha Agarwal
Deeksha Agarwal
I love making mobile apps:)