Skip to content
This repository was archived by the owner on Jul 2, 2025. It is now read-only.

Commit c07e51f

Browse files
1. Add login fragment. Seperate login process from MainActivity
2. Reduce unnecessary variables in MainActivity 3. Using ViewModel to save the user 4. Fix bug in firebaseAuthWithGoogle addOnCompleteListener 5. Remove the activity in backstack.
1 parent 76c28af commit c07e51f

File tree

7 files changed

+238
-111
lines changed

7 files changed

+238
-111
lines changed

android/canonical/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ dependencies {
3838
implementation 'androidx.appcompat:appcompat:1.1.0'
3939
implementation "androidx.fragment:fragment-ktx:1.2.5"
4040
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
41-
implementation 'com.google.android.gms:play-services-auth:18.0.0'
41+
implementation 'com.google.android.gms:play-services-auth:18.1.0'
4242
implementation 'com.google.android.material:material:1.1.0'
4343
implementation 'com.google.android.gms:play-services-maps:17.0.0'
4444
implementation 'com.google.android.gms:play-services-location:17.0.0'
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package com.google.samples.quickstart.canonical
2+
3+
import android.content.Intent
4+
import android.os.Bundle
5+
import android.util.Log
6+
import androidx.fragment.app.Fragment
7+
import android.view.LayoutInflater
8+
import android.view.View
9+
import android.view.ViewGroup
10+
import androidx.lifecycle.ViewModelProviders
11+
import com.google.android.gms.auth.api.signin.GoogleSignIn
12+
import com.google.android.gms.common.SignInButton
13+
import com.google.android.gms.common.api.ApiException
14+
import com.google.firebase.auth.GoogleAuthProvider
15+
16+
// TODO: Rename parameter arguments, choose names that match
17+
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
18+
private const val ARG_PARAM1 = "param1"
19+
private const val ARG_PARAM2 = "param2"
20+
21+
/**
22+
* A simple [Fragment] subclass.
23+
* Use the [LoginFragment.newInstance] factory method to
24+
* create an instance of this fragment.
25+
*/
26+
class LoginFragment : Fragment() {
27+
// TODO: Rename and change types of parameters
28+
private var param1: String? = null
29+
private var param2: String? = null
30+
private lateinit var signInVM : SignInViewModel
31+
32+
private fun signIn() {
33+
val signInIntent = signInVM.getGoogleSignInClient().signInIntent
34+
startActivityForResult(signInIntent, RC_SIGN_IN)
35+
}
36+
37+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
38+
super.onActivityResult(requestCode, resultCode, data)
39+
40+
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
41+
if (requestCode == RC_SIGN_IN) {
42+
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
43+
if (task.isSuccessful) {
44+
try {
45+
// Google Sign In was successful, authenticate with Firebase
46+
val account = task.getResult(ApiException::class.java)!!
47+
Log.d(TAG, "Google Sign In was successful:" + account.id)
48+
firebaseAuthWithGoogle(account.idToken!!)
49+
val intent = Intent(context, MainActivity::class.java)
50+
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
51+
startActivity(intent)
52+
} catch (e: ApiException) {
53+
// Google Sign In failed
54+
Log.w(TAG, "Google sign in failed", e)
55+
}
56+
} else {
57+
Log.w(TAG, "Google sign in unsuccessful")
58+
}
59+
60+
}
61+
// No other requestCode, ignore it.
62+
}
63+
64+
65+
private fun firebaseAuthWithGoogle(idToken: String) {
66+
Log.d(TAG, "firebaseAuthWithGoogle start")
67+
val credential = GoogleAuthProvider.getCredential(idToken, null)
68+
Log.d(TAG, "firebaseAuthWithGoogle credential:$credential")
69+
signInVM.getFirebaseAuth().signInWithCredential(credential)
70+
.addOnCompleteListener { task ->
71+
Log.d(TAG, "firebase firebaseAuthWithGoogle:task check")
72+
if (task.isSuccessful) {
73+
// Firebase Sign in success, update UI with the signed-in user's information
74+
Log.d(TAG, "firebase signInWithCredential:success")
75+
val user = signInVM.getFirebaseAuth().currentUser
76+
Log.d(TAG, "firebase signed-in user's Email:" + user!!.email)
77+
} else {
78+
// If sign in fails, log a message to the user.
79+
Log.w(TAG, "signInWithCredential:failure", task.exception)
80+
}
81+
}
82+
}
83+
84+
override fun onCreate(savedInstanceState: Bundle?) {
85+
super.onCreate(savedInstanceState)
86+
arguments?.let {
87+
param1 = it.getString(ARG_PARAM1)
88+
param2 = it.getString(ARG_PARAM2)
89+
}
90+
91+
signInVM = activity?.run {
92+
ViewModelProviders.of(this)[SignInViewModel::class.java]
93+
} ?: throw Exception("Null Activity")
94+
95+
}
96+
97+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
98+
savedInstanceState: Bundle?): View? {
99+
// Inflate the layout for this fragment
100+
return inflater.inflate(R.layout.fragment_login, container, false)
101+
}
102+
103+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
104+
super.onViewCreated(view, savedInstanceState)
105+
view.findViewById<SignInButton>(R.id.sign_in_button).setOnClickListener {
106+
signIn()
107+
}
108+
}
109+
110+
companion object {
111+
/**
112+
* Use this factory method to create a new instance of
113+
* this fragment using the provided parameters.
114+
*
115+
* @param param1 Parameter 1.
116+
* @param param2 Parameter 2.
117+
* @return A new instance of fragment LoginFragment.
118+
*/
119+
const val RC_SIGN_IN = 0
120+
const val TAG = "Login fragment"
121+
// TODO: Rename and change types and number of parameters
122+
@JvmStatic fun newInstance(param1: String, param2: String) =
123+
LoginFragment().apply {
124+
arguments = Bundle().apply {
125+
putString(ARG_PARAM1, param1)
126+
putString(ARG_PARAM2, param2)
127+
}
128+
}
129+
}
130+
}
Lines changed: 24 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,23 @@
11
package com.google.samples.quickstart.canonical
22

3-
import android.content.Intent
43
import androidx.appcompat.app.AppCompatActivity
54
import android.os.Bundle
65
import android.util.Log
6+
import androidx.constraintlayout.widget.ConstraintLayout
77
import androidx.fragment.app.FragmentTransaction
8+
import androidx.lifecycle.ViewModelProviders
89
import com.google.android.gms.auth.api.signin.GoogleSignIn
9-
import com.google.android.gms.auth.api.signin.GoogleSignInClient
10-
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
11-
import com.google.android.gms.common.SignInButton
12-
import com.google.android.gms.common.api.ApiException
1310
import com.google.android.material.bottomnavigation.BottomNavigationView
14-
import com.google.firebase.auth.FirebaseAuth
15-
import com.google.firebase.auth.GoogleAuthProvider
1611

1712
class MainActivity : AppCompatActivity() {
18-
lateinit var googleSignInClient: GoogleSignInClient
19-
private lateinit var auth: FirebaseAuth
2013

21-
private fun googleSignInInit() {
22-
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
23-
.requestIdToken(getString(R.string.default_web_client_id))
24-
.requestEmail()
25-
.build()
26-
27-
googleSignInClient = GoogleSignIn.getClient(this, gso)
28-
}
29-
30-
private fun signIn() {
31-
auth = FirebaseAuth.getInstance()
32-
val signInIntent = googleSignInClient.signInIntent
33-
startActivityForResult(signInIntent, RC_SIGN_IN)
34-
}
35-
36-
37-
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
38-
super.onActivityResult(requestCode, resultCode, data)
39-
40-
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
41-
if (requestCode == RC_SIGN_IN) {
42-
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
43-
if (task.isSuccessful) {
44-
try {
45-
// Google Sign In was successful, authenticate with Firebase
46-
val account = task.getResult(ApiException::class.java)!!
47-
Log.d(TAG, "firebaseAuthWithGoogle:" + account.id)
48-
firebaseAuthWithGoogle(account.idToken!!)
49-
setContentView(R.layout.activity_main)
50-
setupNavigationBar()
51-
} catch (e: ApiException) {
52-
// Google Sign In failed
53-
Log.w(TAG, "Google sign in failed", e)
54-
}
55-
} else {
56-
Log.w(TAG, "Google sign in unsuccessful")
57-
}
58-
59-
}
60-
// No other requestCode, ignore it.
61-
}
62-
63-
64-
private fun firebaseAuthWithGoogle(idToken: String) {
65-
val credential = GoogleAuthProvider.getCredential(idToken, null)
66-
auth.signInWithCredential(credential)
67-
.addOnCompleteListener(this) { task ->
68-
if (task.isSuccessful) {
69-
// Firebase Sign in success, update UI with the signed-in user's information
70-
Log.d(FIREBASE_TAG, "signInWithCredential:success")
71-
val user = auth.currentUser
72-
Log.d(FIREBASE_TAG, "signed-in user's Email:" + user!!.email)
73-
} else {
74-
// If sign in fails, log a message to the user.
75-
Log.w(FIREBASE_TAG, "signInWithCredential:failure", task.exception)
76-
}
77-
}
78-
}
14+
private lateinit var signInVM : SignInViewModel
7915

8016

8117
private fun setupNavigationBar() {
82-
val runFragment = RunFragment()
8318
supportFragmentManager
8419
.beginTransaction()
85-
.replace(R.id.fragment_container, runFragment)
20+
.replace(R.id.fragment_container, RunFragment())
8621
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
8722
.commit()
8823

@@ -91,30 +26,28 @@ class MainActivity : AppCompatActivity() {
9126
when (item.itemId) {
9227

9328
R.id.bottom_navigation_item_run -> {
94-
val runFragment = RunFragment()
9529
supportFragmentManager
9630
.beginTransaction()
97-
.replace(R.id.fragment_container, runFragment)
31+
.replace(R.id.fragment_container, RunFragment())
9832
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
9933
.commit()
10034
true
10135
}
10236

10337
R.id.bottom_navigation_item_map -> {
104-
val mapsFragment = MapsFragment()
38+
// val mapsFragment = MapsFragment()
10539
supportFragmentManager
10640
.beginTransaction()
107-
.replace(R.id.fragment_container, mapsFragment)
41+
.replace(R.id.fragment_container, MapsFragment())
10842
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
10943
.commit()
11044
true
11145
}
11246

11347
R.id.bottom_navigation_item_profile -> {
114-
val meFragment = MeFragment()
11548
supportFragmentManager
11649
.beginTransaction()
117-
.replace(R.id.fragment_container, meFragment)
50+
.replace(R.id.fragment_container, MeFragment())
11851
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
11952
.commit()
12053
true
@@ -125,34 +58,37 @@ class MainActivity : AppCompatActivity() {
12558
}
12659
}
12760

128-
12961
override fun onCreate(savedInstanceState: Bundle?) {
13062
super.onCreate(savedInstanceState)
13163
setContentView(R.layout.activity_main)
13264

133-
googleSignInInit()
134-
setupNavigationBar()
65+
signInVM = ViewModelProviders.of(this)[SignInViewModel::class.java]
66+
signInVM.signInInit(this, this)
13567

68+
setupNavigationBar()
13669
}
13770

138-
13971
override fun onStart() {
14072
super.onStart()
73+
14174
val account = GoogleSignIn.getLastSignedInAccount(this)
142-
if (account == null) {
143-
setContentView(R.layout.login_in_page)
144-
findViewById<SignInButton>(R.id.sign_in_button).setOnClickListener {
145-
signIn()
146-
}
75+
account?.let {
76+
Log.d(TAG, "Already login")
77+
} ?: run {
78+
Log.d(TAG, "No login. Update UI")
79+
findViewById<ConstraintLayout>(R.id.main_activity_view).removeAllViews()
80+
81+
supportFragmentManager
82+
.beginTransaction()
83+
.replace(R.id.main_activity_view, LoginFragment())
84+
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
85+
.commit()
14786
}
14887
}
14988

15089

15190
companion object {
152-
private const val RC_SIGN_IN = 0
153-
private const val TAG = "MainActivity-Login"
154-
private const val FIREBASE_TAG = "MainAct-firebase-Login"
91+
private const val TAG = "MainActivity"
15592
}
15693

157-
15894
}

android/canonical/app/src/main/java/com/google/samples/quickstart/canonical/MeFragment.kt

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ import android.view.View
99
import android.view.ViewGroup
1010
import android.widget.Button
1111
import android.widget.TextView
12-
import com.google.android.gms.auth.api.signin.GoogleSignIn
13-
import com.google.firebase.auth.FirebaseAuth
12+
import androidx.lifecycle.ViewModelProviders
1413

1514
private const val ARG_PARAM1 = "param1"
1615
private const val ARG_PARAM2 = "param2"
1716

18-
1917
/**
2018
* A simple [Fragment] subclass.
2119
* Use the [MeFragment.newInstance] factory method to
@@ -25,13 +23,19 @@ class MeFragment : Fragment() {
2523
// TODO: Rename and change types of parameters
2624
private var param1: String? = null
2725
private var param2: String? = null
26+
private lateinit var signInVM : SignInViewModel
2827

2928
override fun onCreate(savedInstanceState: Bundle?) {
3029
super.onCreate(savedInstanceState)
3130
arguments?.let {
3231
param1 = it.getString(ARG_PARAM1)
3332
param2 = it.getString(ARG_PARAM2)
3433
}
34+
35+
signInVM = activity?.run {
36+
ViewModelProviders.of(this)[SignInViewModel::class.java]
37+
} ?: throw Exception("Null Activity")
38+
3539
}
3640

3741

@@ -49,24 +53,14 @@ class MeFragment : Fragment() {
4953
val logoutButton : Button = view.findViewById(R.id.logout_button)
5054
logoutButton.setOnClickListener {
5155
// Sign out both Google account and Firebase
52-
FirebaseAuth.getInstance().signOut()
53-
(activity as MainActivity).googleSignInClient.signOut().addOnCompleteListener {
56+
signInVM.signOut()?.addOnCompleteListener {
5457
val intent = Intent(context, MainActivity::class.java)
58+
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
5559
startActivity(intent)
5660
}
5761
}
58-
}
59-
60-
61-
override fun onStart() {
62-
super.onStart()
63-
val account = GoogleSignIn.getLastSignedInAccount(this.context)
64-
account?.let {
65-
Log.i(ME_TAG, "Already login")
66-
view?.findViewById<TextView>(R.id.textView)?.text = account.displayName
67-
} ?.run {
68-
Log.i(ME_TAG, "No login")
69-
}
62+
// update UI
63+
view.findViewById<TextView>(R.id.textView)?.text = signInVM.getFirebaseAuth().currentUser?.email
7064
}
7165

7266

0 commit comments

Comments
 (0)