Skip to content

Connected Firebase console to Google login button and stored Login info for use in HomeScreen#5

Open
wenja0618 wants to merge 1 commit intomainfrom
jarmin/onboarding
Open

Connected Firebase console to Google login button and stored Login info for use in HomeScreen#5
wenja0618 wants to merge 1 commit intomainfrom
jarmin/onboarding

Conversation

@wenja0618
Copy link
Copy Markdown
Contributor

@wenja0618 wenja0618 commented Apr 16, 2026

Overview

Connected Firebase console to Google login button
Stored Login info for use in HomeScreen and upcoming screens

Changes Made

Altered build.gradle.kts to import necessary Firebase-related libraries
Created GlobleState.kt to store the Google login account's name for use in other pages
Altered HomeScreen.kt to print out the Google login account's first name instead of Arielle
Altered Onboarding.kt to have the Google login button open a Google login page
Altered libs.versions.toml to have the necessary Firebase-related library versions

Demo

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

    • Google Sign-In authentication: users can now securely log in using their Google account
    • Personalized user experience: home screen greeting now displays the authenticated user's first name
  • Improvements

    • Enhanced error handling: sign-in failures now display informative notifications to help users troubleshoot issues

…nection from Onboarding to HomeScreen based on login email
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 16, 2026

📝 Walkthrough

Walkthrough

This 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

Cohort / File(s) Summary
Dependency Configuration
gradle/libs.versions.toml, app/build.gradle.kts
Added Firebase BoM, Firebase Auth, Play Services Auth libraries and Google Services Gradle plugin with pinned versions (Firebase BoM 34.12.0, Google Services 4.4.4, Play Services Auth 21.5.1).
Global State Management
app/src/main/java/com/cornellappdev/chimes/GlobalState.kt
New Compose-backed global state object holding mutable userName property (default: "Ithacan") via mutableStateOf for reactive state management.
Authentication Flow
app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt
Implemented Google Sign-In + Firebase authentication: activity result launcher for StartActivityForResult, Google Sign-In with ID token from config, Firebase credential exchange, GlobalState.userName population from authenticated user's display name, and Toast-based error handling for API and sign-in failures.
UI State Integration
app/src/main/java/com/cornellappdev/chimes/ui/screens/HomeScreen.kt
Updated greeting text to dynamically display user's first name from GlobalState.userName instead of hardcoded text.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • AndrewCheung360
  • Gregor-Guerrier

Poem

🐰 Hops and credentials, a tale so fine,
Google signs in with a dance divine,
Firebase guards what we hold so dear,
Global state whispers a name most clear—
Welcome home, dear user, the auth is here!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: connecting Firebase to Google login and storing login info in GlobalState for use across screens including HomeScreen.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jarmin/onboarding

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 21e6fc3 and 66c49d8.

📒 Files selected for processing (5)
  • app/build.gradle.kts
  • app/src/main/java/com/cornellappdev/chimes/GlobalState.kt
  • app/src/main/java/com/cornellappdev/chimes/ui/screens/HomeScreen.kt
  • app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt
  • gradle/libs.versions.toml

Comment on lines +7 to +9
object GlobalState {
var userName by mutableStateOf("Ithacan")
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Comment on lines +61 to +62
val context = LocalContext.current
val auth = remember { Firebase.auth }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, find the Onboarding.kt file
fd -t f "Onboarding.kt" app/src/main/java

Repository: 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 -130

Repository: 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 -30

Repository: 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 2

Repository: 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 -50

Repository: 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.

Comment on lines +102 to +120
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()
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
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.

Copy link
Copy Markdown
Member

@AndrewCheung360 AndrewCheung360 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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() ?: ""} ☀️",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member

@AndrewCheung360 AndrewCheung360 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants