Connected Firebase console to Google login button and stored Login info for use in HomeScreen#5
Connected Firebase console to Google login button and stored Login info for use in HomeScreen#5
Conversation
…nection from Onboarding to HomeScreen based on login email
📝 WalkthroughWalkthroughThis PR integrates Google Sign-In and Firebase authentication into the onboarding flow. Changes add Firebase and Play Services dependencies to the build configuration, introduce a global state holder for user information, implement the Google Sign-In and Firebase auth logic in the Onboarding screen, and update the HomeScreen to display the authenticated user's name dynamically. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Onboarding as Onboarding Screen
participant GoogleSignIn as Google Sign-In
participant FirebaseAuth as Firebase Auth
participant GlobalState
participant HomeScreen
User->>Onboarding: Click "Log-in with Google"
Onboarding->>GoogleSignIn: Launch sign-in intent
GoogleSignIn->>GoogleSignIn: User authenticates
GoogleSignIn-->>Onboarding: Return auth result with credential
alt Sign-In Success
Onboarding->>FirebaseAuth: Exchange credential for Firebase auth
FirebaseAuth->>FirebaseAuth: Create/verify user session
FirebaseAuth-->>Onboarding: Return authenticated user
Onboarding->>GlobalState: Set userName from user.displayName
GlobalState-->>Onboarding: State updated
Onboarding->>HomeScreen: Trigger onLoginClick()
else Sign-In/Auth Failure
Onboarding->>Onboarding: Show Toast with error message
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/main/java/com/cornellappdev/chimes/GlobalState.kt`:
- Around line 7-9: GlobalState.object exposes a process-local
mutableStateOf("Ithacan") (userName) which resets on process death; replace uses
of GlobalState.userName with an app-scoped solution: create an
Application-scoped ViewModel/Repository that reads the authenticated session
(e.g., from your auth SDK or DataStore/SavedStateHandle) and exposes a
LiveData/StateFlow/MutableState for the current user's display name; hydrate
that state from the real session on app start and observe it in UI composables
instead of referencing GlobalState.userName so the UI reflects the actual
signed-in user across process restarts.
In `@app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt`:
- Around line 102-120: The Google sign-in launcher (googleSignInLauncher) treats
a cancelled account picker as an auth failure because it always tries to parse
the intent; modify the ActivityResult callback to first check the result status
and data (e.g., if result.resultCode != Activity.RESULT_OK or result.data ==
null) and treat that path as a cancel (no error toast, optionally return or call
a cancel handler), otherwise proceed to call
GoogleSignIn.getSignedInAccountFromIntent(result.data) and the existing
try/catch for ApiException and Firebase sign-in with
GoogleAuthProvider.getCredential; ensure you do not show the "Google Sign-In
failed" Toast when the user simply dismissed the chooser.
- Around line 61-62: The Firebase.auth initialization in Onboarding (val auth =
remember { Firebase.auth }) runs during previews and can crash
OnboardingPreview; guard this by checking LocalInspectionMode.current (or accept
an injected auth parameter) and only call Firebase.auth when not in inspection
mode — e.g., in Onboarding use a conditional/nullable auth (or a preview
FakeAuth) so OnboardingPreview can render without a FirebaseApp; update the
Onboarding signature or the remember block to reference
LocalInspectionMode.current and avoid calling Firebase.auth during preview.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9c02c2e4-724d-4214-8584-d32aa294fe7e
📒 Files selected for processing (5)
app/build.gradle.ktsapp/src/main/java/com/cornellappdev/chimes/GlobalState.ktapp/src/main/java/com/cornellappdev/chimes/ui/screens/HomeScreen.ktapp/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.ktgradle/libs.versions.toml
| object GlobalState { | ||
| var userName by mutableStateOf("Ithacan") | ||
| } |
There was a problem hiding this comment.
Don't use a process-local singleton as the logged-in user source of truth.
This state resets to "Ithacan" on process death/app relaunch, so the UI can drift from the actual signed-in user. For auth-backed data, please hydrate from an app-scoped ViewModel/repository tied to the real session instead of a global object.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/src/main/java/com/cornellappdev/chimes/GlobalState.kt` around lines 7 -
9, GlobalState.object exposes a process-local mutableStateOf("Ithacan")
(userName) which resets on process death; replace uses of GlobalState.userName
with an app-scoped solution: create an Application-scoped ViewModel/Repository
that reads the authenticated session (e.g., from your auth SDK or
DataStore/SavedStateHandle) and exposes a LiveData/StateFlow/MutableState for
the current user's display name; hydrate that state from the real session on app
start and observe it in UI composables instead of referencing
GlobalState.userName so the UI reflects the actual signed-in user across process
restarts.
| val context = LocalContext.current | ||
| val auth = remember { Firebase.auth } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find the Onboarding.kt file
fd -t f "Onboarding.kt" app/src/main/javaRepository: cuappdev/chimes-android
Length of output: 134
🏁 Script executed:
# Read the relevant section of Onboarding.kt, focusing on lines 1-120 to see the initialization and preview
cat -n app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt | head -130Repository: cuappdev/chimes-android
Length of output: 6400
🏁 Script executed:
# Also check the OnboardingPreview function around line 373-376
cat -n app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt | tail -30Repository: cuappdev/chimes-android
Length of output: 1234
🏁 Script executed:
# Check if there are any preview guards or LocalInspectionMode usage in this file
rg "LocalInspectionMode|@Preview" app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt -A 5 -B 2Repository: cuappdev/chimes-android
Length of output: 135
🏁 Script executed:
# Check if Firebase is used elsewhere in preview composables to see the pattern
fd -t f "Preview.kt" app/src/main/java --exec grep -l "Firebase" {} \;Repository: cuappdev/chimes-android
Length of output: 49
🏁 Script executed:
# Check for other preview implementations in the codebase that might use Firebase
rg "@Preview" app/src/main/java -A 5 | rg -B 5 "Firebase" | head -50Repository: cuappdev/chimes-android
Length of output: 49
Guard Firebase initialization in preview mode.
OnboardingPreview() calls Onboarding() directly, so the Firebase.auth initialization at line 62 executes during preview rendering. Preview processes typically don't have a default FirebaseApp configured, which will break the preview. Add a preview guard (e.g., LocalInspectionMode.current) or inject the auth dependency instead.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt` around
lines 61 - 62, The Firebase.auth initialization in Onboarding (val auth =
remember { Firebase.auth }) runs during previews and can crash
OnboardingPreview; guard this by checking LocalInspectionMode.current (or accept
an injected auth parameter) and only call Firebase.auth when not in inspection
mode — e.g., in Onboarding use a conditional/nullable auth (or a preview
FakeAuth) so OnboardingPreview can render without a FirebaseApp; update the
Onboarding signature or the remember block to reference
LocalInspectionMode.current and avoid calling Firebase.auth during preview.
| val googleSignInLauncher = rememberLauncherForActivityResult( | ||
| contract = ActivityResultContracts.StartActivityForResult() | ||
| ) { result -> | ||
| val task = GoogleSignIn.getSignedInAccountFromIntent(result.data) | ||
| try { | ||
| val account = task.getResult(ApiException::class.java)!! | ||
| val credential = GoogleAuthProvider.getCredential(account.idToken, null) | ||
| auth.signInWithCredential(credential).addOnCompleteListener { | ||
| if (it.isSuccessful) { | ||
| GlobalState.userName = it.result.user?.displayName ?: "" | ||
| onLoginClick() | ||
| } else { | ||
| Toast.makeText(context, "Firebase Authentication failed: ${it.exception?.message}", Toast.LENGTH_SHORT).show() | ||
| } | ||
| } | ||
| } catch (e: ApiException) { | ||
| Toast.makeText(context, "Google Sign-In failed: ${e.message}", Toast.LENGTH_SHORT).show() | ||
| } | ||
| } |
There was a problem hiding this comment.
Treat a dismissed Google chooser as cancel, not auth failure.
If the user backs out of the account picker, this callback still tries to parse the intent and shows the failure toast. That turns a normal cancel path into an error state.
Suggested fix
+import android.app.Activity
+
val googleSignInLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult()
) { result ->
+ if (result.resultCode != Activity.RESULT_OK) {
+ return@rememberLauncherForActivityResult
+ }
val task = GoogleSignIn.getSignedInAccountFromIntent(result.data)
try {
val account = task.getResult(ApiException::class.java)!!📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| val googleSignInLauncher = rememberLauncherForActivityResult( | |
| contract = ActivityResultContracts.StartActivityForResult() | |
| ) { result -> | |
| val task = GoogleSignIn.getSignedInAccountFromIntent(result.data) | |
| try { | |
| val account = task.getResult(ApiException::class.java)!! | |
| val credential = GoogleAuthProvider.getCredential(account.idToken, null) | |
| auth.signInWithCredential(credential).addOnCompleteListener { | |
| if (it.isSuccessful) { | |
| GlobalState.userName = it.result.user?.displayName ?: "" | |
| onLoginClick() | |
| } else { | |
| Toast.makeText(context, "Firebase Authentication failed: ${it.exception?.message}", Toast.LENGTH_SHORT).show() | |
| } | |
| } | |
| } catch (e: ApiException) { | |
| Toast.makeText(context, "Google Sign-In failed: ${e.message}", Toast.LENGTH_SHORT).show() | |
| } | |
| } | |
| import android.app.Activity | |
| val googleSignInLauncher = rememberLauncherForActivityResult( | |
| contract = ActivityResultContracts.StartActivityForResult() | |
| ) { result -> | |
| if (result.resultCode != Activity.RESULT_OK) { | |
| return@rememberLauncherForActivityResult | |
| } | |
| val task = GoogleSignIn.getSignedInAccountFromIntent(result.data) | |
| try { | |
| val account = task.getResult(ApiException::class.java)!! | |
| val credential = GoogleAuthProvider.getCredential(account.idToken, null) | |
| auth.signInWithCredential(credential).addOnCompleteListener { | |
| if (it.isSuccessful) { | |
| GlobalState.userName = it.result.user?.displayName ?: "" | |
| onLoginClick() | |
| } else { | |
| Toast.makeText(context, "Firebase Authentication failed: ${it.exception?.message}", Toast.LENGTH_SHORT).show() | |
| } | |
| } | |
| } catch (e: ApiException) { | |
| Toast.makeText(context, "Google Sign-In failed: ${e.message}", Toast.LENGTH_SHORT).show() | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt` around
lines 102 - 120, The Google sign-in launcher (googleSignInLauncher) treats a
cancelled account picker as an auth failure because it always tries to parse the
intent; modify the ActivityResult callback to first check the result status and
data (e.g., if result.resultCode != Activity.RESULT_OK or result.data == null)
and treat that path as a cancel (no error toast, optionally return or call a
cancel handler), otherwise proceed to call
GoogleSignIn.getSignedInAccountFromIntent(result.data) and the existing
try/catch for ApiException and Firebase sign-in with
GoogleAuthProvider.getCredential; ensure you do not show the "Google Sign-In
failed" Toast when the user simply dismissed the chooser.
AndrewCheung360
left a comment
There was a problem hiding this comment.
Make sure to add the google-services json and pin it in the chimes-android channel.
| ) { | ||
| Text( | ||
| text = "Hi, Arielle ☀\uFE0F", | ||
| text = "Hi, ${GlobalState.userName.split(" ").firstOrNull() ?: ""} ☀️", |
There was a problem hiding this comment.
We should ideally not be using global state for the user name. This should be something we handle in the HomeScreen ViewModel UiState
| import androidx.compose.runtime.mutableStateOf | ||
| import androidx.compose.runtime.setValue | ||
|
|
||
| object GlobalState { |
There was a problem hiding this comment.
Instead of a global state we should use Repositories and ViewModels for screens to handle state management and business logic
| onLoginClick: () -> Unit = {} | ||
| ) { | ||
| val context = LocalContext.current | ||
| val auth = remember { Firebase.auth } |
There was a problem hiding this comment.
We should move all firebase authentication logic into some sort of Auth repository and then the viewmodel can make use of some of the defined repository functions and contain the ui states which the screen can then use
There was a problem hiding this comment.
We should also add dependency injection with Hilt and Hilt ViewModel ideally to this app and we can then inject the repository into the necessary viewmodels.
There was a problem hiding this comment.
You can take a look at some example android mvvm repositories for reference. Resell, hustle, uplift, etc. are some codebases you can maybe take a look at, but they're not perfect, so try not to blindly copy and make sure to do due research.
AndrewCheung360
left a comment
There was a problem hiding this comment.
Thanks for trying to add google sign in! I left some comments about setting up the MVVM architecture instead of using some global state. This feature is pretty complicated, especially for someone just starting, so don't worry too much about getting it right the first time.
Overview
Connected Firebase console to Google login button
Stored Login info for use in HomeScreen and upcoming screens
Changes Made
Altered
build.gradle.ktsto import necessary Firebase-related librariesCreated
GlobleState.ktto store the Google login account's name for use in other pagesAltered
HomeScreen.ktto print out the Google login account's first name instead of ArielleAltered
Onboarding.ktto have the Google login button open a Google login pageAltered
libs.versions.tomlto have the necessary Firebase-related library versionsDemo
https://github.com/user-attachments/assets/433dbd15-9e87-4421-b2d1-8167195ee2a2
I had already logged with an account with first name "Alt" prior to the screen recording which is why you see the Google login page not popping up.
Test Method
Motorola Edge 2022
Summary by CodeRabbit
New Features
Improvements