Skip to content

Commit

Permalink
Feat : Implement Google Login with Firebase
Browse files Browse the repository at this point in the history
1. Implement Splash Activity.
- Set delay(1000) and then move Activity to Login Activity
2. Implement Google Login
- Receive IDToken from Google Server
- Backend server communication not implemented
- Auto Login not implemented
3. Add KTX libraries
  • Loading branch information
ksh-g001 committed Jan 11, 2024
1 parent 664f443 commit 125bddc
Show file tree
Hide file tree
Showing 17 changed files with 304 additions and 11 deletions.
20 changes: 20 additions & 0 deletions android/HowAboutTrip/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties

plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services")
id("kotlin-kapt")
}

Expand All @@ -21,6 +24,10 @@ android {
}

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

buildConfigField("String", "GOOGLE_OAUTH_ID", getApiKey("google_oauth_id"))
buildConfigField("String", "GOOGLE_MAP_API_KEY", getApiKey("google_map_api_key"))
buildConfigField("String", "GOOGLE_SERVER_ID", getApiKey("google_server_id"))
}

buildTypes {
Expand All @@ -41,13 +48,26 @@ android {
}
}

fun getApiKey(propertyKey: String):String = gradleLocalProperties(rootDir).getProperty(propertyKey)

dependencies {

implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.11.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("com.airbnb.android:lottie:6.3.0")

implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
implementation("androidx.fragment:fragment-ktx:1.7.0-alpha07")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")

implementation(platform("com.google.firebase:firebase-bom:32.7.0"))
implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-auth:22.3.0")
implementation("com.google.android.gms:play-services-auth:20.7.0")


testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
Expand Down
47 changes: 47 additions & 0 deletions android/HowAboutTrip/app/google-services.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"project_info": {
"project_number": "740845966307",
"project_id": "howabouttrip",
"storage_bucket": "howabouttrip.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:740845966307:android:71aff1bfe733b688ad46d6",
"android_client_info": {
"package_name": "com.project.how"
}
},
"oauth_client": [
{
"client_id": "740845966307-oulmuvm5mv595vlu9hf1a3j5n4ouvskg.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.project.how",
"certificate_hash": "8f29dbe96504294182411cc8b5af35fee8e57de8"
}
},
{
"client_id": "740845966307-vhqequ0l999eglm9p87su14da4bjreid.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDg0_7_UQD4gNj9XmKnQZpBGREl0r9CZ_Q"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "740845966307-vhqequ0l999eglm9p87su14da4bjreid.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
6 changes: 5 additions & 1 deletion android/HowAboutTrip/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
Expand All @@ -26,6 +27,9 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".view.activity.MainActivity"
android:exported="false"/>
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.project.how.model

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider

class LoginRepository {
private val firebaseAuth = FirebaseAuth.getInstance()
private val _userLiveData = MutableLiveData<FirebaseUser>()
val userLiveData: LiveData<FirebaseUser>
get() = _userLiveData

fun getUser(idToken: String) {
val credential = GoogleAuthProvider.getCredential(idToken, null)
firebaseAuth.signInWithCredential(credential).addOnCompleteListener{
if(it.isSuccessful){
_userLiveData.postValue(firebaseAuth.currentUser)
} else{
Log.e("GoogleAuthRepository", "getUser is failed\n${it.exception}")
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,58 @@
package com.project.how.view.activity

import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.databinding.DataBindingUtil
import com.google.android.gms.auth.api.identity.BeginSignInRequest
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.api.ApiException
import com.project.how.BuildConfig
import com.project.how.R
import com.project.how.databinding.ActivityLoginBinding
import com.project.how.view_model.LoginViewModel

class LoginActivity : AppCompatActivity() {
private lateinit var binding : ActivityLoginBinding
private val viewModel: LoginViewModel by viewModels()
private lateinit var activityResultLauncher : ActivityResultLauncher<Intent>
private lateinit var googleSignInRequest: GoogleSignInClient

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
binding = DataBindingUtil.setContentView(this, R.layout.activity_login)
binding.login = this
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(BuildConfig.GOOGLE_SERVER_ID)
.requestEmail()
.build()
googleSignInRequest = GoogleSignIn.getClient(this, gso)
activityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
if(it.resultCode == Activity.RESULT_OK) {
val task = GoogleSignIn.getSignedInAccountFromIntent(it.data)
try {
val account = task.result
viewModel.getUser(account.idToken!!)
Log.d("activityResultLauncher", "Login Success\nidToken : ${account.idToken}\nid : ${account.id}\nemail : ${account.email}")
startActivity(Intent(this, MainActivity::class.java))
} catch (e: Exception){
Log.e("activityResultLauncher", "Login Failed\nError : ${e.stackTrace}\n${e.message}")
}
}
}

binding.googleLogin.setOnClickListener {
activityResultLauncher.launch(googleSignInRequest.signInIntent)
binding.lottie.pauseAnimation()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.project.how.view.activity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.project.how.R
import com.project.how.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding= DataBindingUtil.setContentView(this, R.layout.activity_main)

}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
package com.project.how.view.activity

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.lifecycleScope
import com.project.how.R
import com.project.how.databinding.ActivitySplashBinding
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class SplashActivity : AppCompatActivity() {
private lateinit var binding : ActivitySplashBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
binding = DataBindingUtil.setContentView(this, R.layout.activity_splash)
binding.splash = this

lifecycleScope.launch {
delay(1000)
startActivity(Intent(this@SplashActivity, LoginActivity::class.java))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.project.how.view_model

import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import com.google.firebase.auth.FirebaseUser
import com.project.how.model.LoginRepository

class LoginViewModel : ViewModel() {
private var loginRepository : LoginRepository = LoginRepository()
private val _userLiveData = loginRepository.userLiveData
val userLiveData: LiveData<FirebaseUser>
get() = _userLiveData

fun getUser(idToken: String){
loginRepository.getUser(idToken)
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
25 changes: 23 additions & 2 deletions android/HowAboutTrip/app/src/main/res/layout/activity_login.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,46 @@

<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie"
android:layout_width="200dp"
android:layout_width="250dp"
android:layout_height="200dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
app:layout_constraintVertical_bias="0.17"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_rawRes="@raw/login_animation" />

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/bm_hanna"
android:gravity="center"
android:text="@string/login_under_text"
android:textSize="16sp"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/lottie" />

<ImageButton
android:id="@+id/google_login"
android:layout_width="250dp"
android:layout_height="100dp"
android:background="@android:color/transparent"
android:scaleType="fitCenter"
android:src="@drawable/google_login"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
app:layout_constraintVertical_bias="0.2"
android:contentDescription="@string/google_login_content_desciption" />

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>
40 changes: 40 additions & 0 deletions android/HowAboutTrip/app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">

<data>
<import type="android.view.View"/>
<variable
name="main"
type="com.project.how.view.activity.MainActivity" />
</data>

<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:fabCradleMargin="5dp"
app:fabCradleRoundedCornerRadius="10dp">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.bottomappbar.BottomAppBar>

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:clickable="true"
app:layout_anchor="@+id/bottomAppBar"
app:layout_anchorGravity="top|center" />


</androidx.coordinatorlayout.widget.CoordinatorLayout>

</layout>
Loading

0 comments on commit 125bddc

Please sign in to comment.