Overview
This programming assignment is another enhancement to the 1024 Game where you will add the following features:
Ask the user to log in with email and password before playing the actual game. This feature allows your game to be played by different players, one at a time.
If the user has not created an account, allow the user to navigation to a different screen for creating a new account
Store the game statistics when the user won or lost the game. The details of the game statistics are provided in a separate section below
Allow the user to browse past game statistics and sort them by some criteria (number of steps, max score, etc.)
UI Design
Login Screen
The login screen should include (at least) the following widgets:
- A text field to enter the user email
- A text field to enter the password (with the password masked)
- A text to show any error messages related to account authentication, i.e. error messages returned by Firebase Authentication
- A button to authenticate the email/password
- A button to navigate to the "New Account" screen

New Account Screen
The new account screen should include (at least) the following widgets:
- A text field to enter the user email
- A text field to enter the user real name
- A text field to enter the password (with the password masked)
- Another text field to confirm the password (with the password masked)
- A text to show any error messages related to account authentication, i.e. error messages returned by Firebase Authentication
- A button to create a new account. This button should stay disabled when both the user email and password fields are empty and when the two password fields do not match.
- A button to the "Cancel" creating a new account and go back to the login screen.
important
After a new account is successfully created the user (real) name shall be stored in Firebase. Subsequent login to your game shall display this real name on the game main screen.

Game Statistics Screen
This screen shall show (at least):
- The user (real) name
- The total number of game sessions have been played
- The average number of steps
- A list of game statistics (one record per row). Show each in a 2- or 3-line format (showing all the details in one line will not fit the available screen width)
- Use two different backgrounds for rows showing a win/lost
- One button to sort the statistics by the number of steps (ascending)
- One button to sort the statistics by the number of steps (descending)
- One button to sort the statistics by date/time
- One button to go back (and resume) the current game

Main (Game) Screen
Modify the main game screen to include two more buttons
- A button to browse the game statistics.
- A button to leave the game
Game Statistics
The game statistics essentially record the achievement of the player after each game session. Each record shall include (at least) the following information:
Number of valid steps to win or lose
The board size
The final state of the game (won/lost)
The maximum score achieved when the user lost/won
For extra credit you can also include extra fields:
- date and time of the game stored in ISO8601 format, i.e. 2023-11-28T19:05:37 for 7:05pm on Nov 28, 2023.
- the number of seconds to win/lose the game
important
The game statistics of each user shall be stored separately from the other users. The common technique in Firestore is to use the Firebase Auth UID as the document ID for each player's data. For instance, if you name the top-level collection players
and you have two users with UID GY238F123h
and Zw9Hz772qR
, then you can use two separate Firestore documents players/GY238F123h
and players/Zw9Hz772qR
to store the details of each player.
Extra Credit Feature: Resume saved game
When the player leaves the game while the game is still in progress, save the current game state to Firestore. On the next login, reload the save game and allow the player to continue where he left off. This means that you have to save the number of steps made, the board size, and the current board content
Resources
Project Setup
As a reference for integrating Firebase Authentication and Firestore in your game app, use the sample code provided on your instructor's GitHub repository. A few important details from the sample code:
- The sample code is provided without the instructor's copy of
google-services.json
. You have to create one yourself (from Firebase project dashboard), by registering it using the package name of the provided sample code. - Setting up Google Services Plugin so your app is linked correctly with your Firebase project.
- To enable access to Firebase from your 1024 game, you must register it separately from (1) above.
It is important that your App build.gradle(.kts)
includes the following "Bill of Materials" libraries (the latest version numbers may be different by the time you read this)
implementation("androidx.compose:compose-bom:2024.04.01")
implementation(platform("com.google.firebase:firebase-bom:31.0.0"))
Instantiating LifeCycle Aware ViewModels
The provided example of GitHub may have created an instance of the view model using explicit construction invocation:
setContent {
val vm = SomeViewModel()
// More code here
}
The above snippet is not aware of lifecycle changes of your Android app. A better approach is to use a delegation by the lifecycle aware function viewModels()
(provided in one of the dependencies):
setContent {
val vm : SomeViewModel by viewModels()
// More code here
}
Likewise, functions which are define with a default initializer for a view model should use the lifecycle aware funcion viewModel()
. Unlike the delegate above (plural name), this function name is singular.
fun MyFunction(/* other args */,
vm: SomeViewModel = SomeViewModel()) { // Don't use this
// more code
}
fun MyFunction(/* other args */,
vm: SomeViewModel = viewModel()) { // USE THIS
// more code
}
Navigate Back
Jetpack Compose NavHostController
provides several function variants to "return" to a previous screen. All the variants essentially pop entries from the (current) navigation stack.
navCtrl.popBackStack() // pop the top-most screen on the navigation stack
navCtrl.popBackStack(route = "whereTo", inclusive = false) // pop all screens until "whereTo" is the topmost
navCtrl.popBackStack(route = "whereTo", inclusive = true) // pop all screens until the screen below "whereTo" is the topmost
Perform Work Outside of (Re)Composition Flow
A @Composable
function may be invoked many times when the UI needs to be updated. However, sometimes we need to hava a block of statement in that @Composable
"excluded" from the UI update cycles (recomposition). Jetpack Compose LaunchedEffect
function can be used for this purpose.
A specific use case in this assigment is loading game statistic data from Firestore.
@Composable
fun GameStatisticsScreen() {
Column {
// Your UI is built here
}
LaunchedEffect(Unit) {
// Invoke a function in view model to load data from Firestore
}
}
Providing Unit
as the argument to LauchedEffect
implies the lambda block executes only once at the time the UI is begin composed (but not during subsequent recompositions).
If a variable is provided as an argument to LaunchedEffect
, the lambda block will execute again when that variable changes.
Deliverables
Be sure that your
google-services.json
is pushed to your Git repoAdd
dulimarh@mail.gvsu.edu
as a member in your Firebase projectInclude the following in your Bb submission:
- The URL to your GitHub repo
- The URL to your Firebase console
Grading Rubrics
Grading Item | Points |
---|---|
Overall navigation flow | 6 |
Login screen | 3 |
Firebase Auth Login & Error handling | 4 |
New Account screen | 4 |
New Account error handling | 3 |
Firestore document per user | 2 |
Firestore game statistics collection per user | 3 |
Game statistics screen design | 4 |
Game statistics row details | 3 |
List of game statistics use two colors for win/lose | 2 |
Sort game statistics by two criteria | 4 |
Deliverables
Be sure to commit your
google-services.json
file into your repository.Create two new user accounts for testing your game
Upload the following to Bb:
- The name of your Firebase Project
- The email and password of the two user accounts created above
Invite
dulimarh@mail.gvsu.edu
to your Firebase Project