Capstone Update #2: Requirements Tab



The purpose of this tab in the STEM Ease app is to show scholars a to-do list of all the requirements they need to complete. When a scholar creates an account the first time they log in, they are asked to enter their year. This year (1, 2, 3, 4, etc.) is used to determine what requirements are displayed in each user’s unique to-do list. So all first-year scholars have a different to-do list than second-years, second-year scholars have a different to-do list than third-years, and so on. The to-do lists and other user information is stored in a Google Firebase Database, so when a user deletes or adds a task, they update their information in the database. The updated information in the database will be saved and the user will see this updated information every time they log into the app.

When viewing the Requirements tab for the first time as a first or second year scholar, it may seem like there are duplicate tasks. These repetitive tasks, like monthly meetings, are displayed the number of times they are required. For example, scholars are required to attend 4 monthly meetings every semester. A total of 8 “1 Monthly Meeting” tasks are displayed in the to-do list to account for all the monthly meetings needed in one year. As scholars attend each meeting, they can cross one monthly meeting item off their to-do list (delete the item) and have the accurate number of monthly meetings remaining in their to-do list. In the database, each item in the to-do list is stored in a dictionary as [String: Array<Int>] pairs. For example, the monthly meeting requirements in the database would be stored as [“1 Monthly Meeting” : [8, 0]]. The String represents what is displayed in the to-do list, the first entry in the Array (8) is the number of times that task is required in one year, and the second entry in the Array (0) represents whether the entire requirement is complete or not. While the first entry of the Array is greater than 0, the second entry stays 0 to represent “not done.” Once the first entry in the Array is 0, the second entry changes to 1 to represent “done.” Below are examples of how adding and deleting tasks works on the Requirements tab and in the database.

Figure 1. Requirements Tab for a Second-Year Scholar (NOTE: More requirements can be seen in the app by scrolling)

Adding a Task

To add a task, the user enters the name of the task into a text box and then presses the “Add” button. When the “Add” button is pressed, the task, or the text from the text box, is immediately displayed in the to-do list. If the task is different from every other task, it is added as a new [String: Array<Int>] pair to the database’s dictionary with the the value [(*string from “Add” text box* : [1, 0]]. If the task is the same as an already present task, the dictionary pair in the database is updated. For example, if a user were to add a ninth “1 Monthly Meeting” task, the database would update the dictionary pair to be [“1 Monthly Meeting” : [9, 0]]. The next time the user logs into the app, they would see 9 “1 Monthly Meeting” tasks instead of 8.


Deleting a Task

To delete a task, the user simply swipes left on the task that they wish to delete. A delete button will show up to the right of the task for the user to confirm that they want to delete the task. Once deleted, the task will immediately be removed from the to-do list. In the database, the dictionary pair has the first entry in its Array decreased by one. If the new first entry is still greater than 0, then nothing else changes. If the new first entry is equal to zero, then the second entry in the Array is changed to 1. For example, the first time a “1 Monthly Meeting” task is deleted, the dictionary pair in the database would change to [“1 Monthly Meeting” : 7, 0]]. The last time that a “1 Monthly Meeting” task is deleted, the dictionary pair would change to [“1 Monthly Meeting” : 0, 1]]. These changes would be saved and reflected in the to-do list the next time the user logs into the app.

Figure 2. Delete button on requirement task.


When designing this tab, I faced several challenges. First, I was challenged when designing the interface for the to-do list. I wanted the to-do list to be entirely gesture driven, like swiping to delete, tapping to add, etc. However, I spent hours trying different YouTube tutorials to implement the tap to add function and even more hours searching Stack Overflow forums for how to troubleshoot the issues that I ran into. I know there is a way to implement this feature (I have an app on my phone, “Clear”, that has this exact feature). But in the interest of time, I decided that this feature was more trouble than it was worth. Users could still delete tasks by swiping, but adding items needed a different approach. I added a text box and and an “Add” button above my to-do list so that users can enter new tasks into the text field and add them to the list with the “Add” button. Although this wasn’t my original intent for the add function, it still functions they way that it needs to. With more time and more experience, I would like to give the tap to add function another try.

Another challenge that I faced was reading the tasks for the to-do list from the database. When a new user signed up, I was able to get the information from the database and display it in the to-do list. However, when a returning user logged in, I got an error saying that I had an invalid reference to the database. This error was very tedious to debug, mainly because I spent the majority of the time debugging the wrong file. Because the error said I had an invalid reference to the database, I focused on the file in which I was retrieving the data from the database. I spent several hours debugging, but no matter what I tried, the app would always crash when a returning user logged in to view their requirements. Since the data could be retrieved when a new user signed up but not when a returning user logged in, I decided to check the file that handles user log ins. I quickly found the error: I called a method to read the requirements from the database before I updated the value of a needed variable. I simply swapped the lines of code so that I updated the variable before I called the method. Once this change was made, I could retrieve the data whether the user was signing up or logging in.