Previously, FoodMe, was an idea for a mobile application that our project mentor came up with to eliminate choice paralysis for individuals choosing where to go eat. Whether in a group setting or individually, everyone has come across the situation of not being able to decide where to, so our goal is to make the decision for you. It made more sense to do this on mobile devices, so we took on the challenge of making a mobile app as opposed to a website. Initially, we are aiming to benefit UC Davis students and to further evolve in the future.
Ethan Luu (Project Manager)
Subhan Baig (Developer)
Hashim Chaudhry (Developer)
Alexis Lydon (Developer)
Arnav Rastogi (Developer)
Ryan Vakhshoori (Developer)
Lana Wong (Developer)
Erika Dimaano (Designer)
Urvi Ganorkar (Designer)
Matthew Park (Designer)
Jan–May 2021 | 15 weeks
Figma, HTML, CSS, React.js, React Native, MongoDB, Express.js, Node.js, as well as both the Yelp and Google APIs.
User Research: Surveys
To kick off our design process, we began by observing users: our goal was to understand who we were designing for and identify different pain points and patterns of behaviors. After sending out a survey, we got 42 responses and some main takeaways were:
- 88.3% of people eat outside 1–4 times a week
- The most common way people decided to order food was through group discussion and through the use of an app.
- The most used apps to order food were food delivery apps such as Doordash and UberEats.
User Research: Interviews
After collecting the user surveys, we moved on to the next stage of our research which was through interviews and focus group observations. We divided our focus groups into three different groups:
- Groups with one person (individual interview)
- Groups with three people (group interview)
- Groups with five people (group interview)
After conducting these interviews, we asked groups to simulate an ordered environment and go from start to finish regarding their food ordering process. In the group setting, we realized there were different phrases and some behavioral patterns between larger groups.
In order to better understand both the qualitative and quantitative data we had gathered, we affinity mapped and synthesized our research. Four main takeaways revolved around the fact that people were interested in a potential app that facilitated the food ordering process in a group environment.
After synthesizing our data, we decided to create user personas that would best replicate the behavioral patterns we noticed, while helping us empathize and further understand our target audience. Interestingly, all three designers working on this project have different personalities and we each created a unique persona.
For User Flow, we decided on 3 main branches for the application. The Home page, Gameplay Page and Profile Page. The Home Page would be the main ‘exploration’ section of the app where users would be able to see nearby restaurants while also being able to filter it according to various different options (price, distance, food type). We also decided on having a ‘Food Category’ tab to allow further specification. The Gameplay page would have the main bulk of the decision-making process of the app which would consist of the loading pages, the actual game, waiting page, and final results. The Profile page would allow the user to edit their profile as well as view their favorite restaurants.
Our Low-Fi wireframes focused on a rough idea of what we wanted our sketches to look like, using inspiration from each member of the team’s vision of the app screen. We eventually settled on two tabs for the home screen, a separation in screens for the Profile section for main profile, editing and favorite restaurants as well as a gameplay screen which consisted of both ‘This of That’ and ‘swiping’ in the form of restaurant ‘cards’.
For branding, we decided on warm colors like yellow and orange as well as an orange-yellow gradient. To evoke the warm feeling that naturally comes with food. Most of our neutral colors were also based on a more warm palette. We also included a ‘correct’ and ‘error’ semantic color to represent the ‘yes’ and ‘no’ during the decision-making gameplay of a user. For typography, we settled on entirely using the Poppins font because it looked very friendly and inviting and is commonly used for most mobile apps. Our Logo uses our orange-yellow gradient and is a fork-like shape that also looks like the letter ‘F’ for Food-off. Additionally, while the original name of the app was FoodMe, we changed it to Food-Off due to our app being a decision-making food app that has different restaurants essentially ‘face-off’ each other.
While creating a branding and design system, we also worked on creating mid-fidelity versions of our designs. Based on the low-fidelity paper sketches, we created wireframes of the screens in greyscale. Unfortunately, due to time constraints, we were unable to prototype at this stage. However, the gameplay sections required a lot of interaction and so we decided to make a working prototype of this gauge feedback.
Due to time constraints, we had to postpone user testing until after completing our first version of the high-fidelity prototype.
From this, we found a couple of key insights…
- Lack of game understanding
In the gameplay section, we found that users showed a lot of hesitation in how to interact with the game. To better introduce the usage of the game portion of this app, we added an onboarding session when the gameplay section is clicked on in the navigation bar. Additionally, we extended the countdown timer before each round of the game in order to allow users to spend more time preparing.
- Group gameplay logistics
Within the gameplay setup, we found inconsistencies in the game data shown. Users have the ability to add as many players as they would like in the game by sending each player a code to join. However, there was no way to see how many players were in the game. This was solved by adding a waiting screen that showed who was being added to the game and previous game data including the number of players who participated.
- Home page carousel and filters
The placement of the home page carousel was changed after user testing and receiving feedback from our PM. We changed the carousel so it seemed more like a scrollable element by adjustin where each carousel item starts on the screen. Originally, they were hugging the left side of the screen, but now they have different start and end points to further accentuate the carousel effect.
Lastly, filters were implemented with the features we inferred from our data and synthesis: Distance, Price, and the use of Yelp’s API in order to create tags and categories for the restaurants. We decided to use Yelp’s API as we wanted to use filters that people were already familiar with.
Final Designs: Login and Home Page
For the login page, we added a concise animation that leads to a login page. Since we use Google Authentication and didn’t have many UI elements, we implemented a gradient background with a lava-lamp effect. This would then lead to a separate window that requires users to log in with their Google account.
The home page can be divided into two different main screens: the “Home” and the “Food” screen. The “Home” screen’s first feature is the “Tap to find out” random food choice of the day. While the app is mainly catered toward group orders, we wanted to include single group orders by implementing this feature that randomly selects a restaurant for the user.
The “Food” screen contains horizontal carousels that allow users to select or explore different food categories. However, while we gamify the food ordering process, we also offer a more direct and streamlined alternative by adding filters and a search bar.
Final Designs: Game Play
The onboarding screens were added as a result of our user testing. Consisting of three screens it details how the gameplay works to help users pick a restaurant. Upon selecting the gameplay icon in the navigation bar for the first time, these screens appear. This will continue to show up each time until the user selects ‘Never Show Again’.
Solo Setup[left], Group Setup[center], Join Group[right]
There are three different types of setup for gameplay.
The solo setup involves a short setup in which the user selects what they would like to create and then play a solo game. They are prompted to add a timer or music to aid in faster decision-making. Finally, the user adds their preferences for restaurants to get started in the game.
The group set up looks the same as solo but instead the user chooses group and has to choose if only the leader will be inputting food preferences or all players. The leader can give the group a name and then a code will be generated for them to send other players to use when joining a game. Clicking ‘Start’ sends the leader to a screen to wait for players and start when they see everyone in.
Joining a group is simple and involves entering the six-digit code the leader of the game has sent. Once they have joined. They will input preferences and then wait for the leader to start the game.
The gameplay screens show what users see once they have clicked start on the game. There are two rounds that each start with a 10-second countdown timer to get users ready to begin. The first round makes use of card swiping in order to add restaurants to a short list that is then used in the ‘This or That’ part of the game. Here, pairs of restaurants are presented to the user for them to choose one and continue till they have a result.
Final Designs: Profile Page
For the profile page, it had 2 main actionable functions. The first function was the ability to edit the profile, specifically to allow preferred nicknames. Since we were using Google Authentication, the initial name for the profile would be based on their Google account. For many reasons, users may not want to be associated with their full Google name on the app. Additionally, in the gameplay waiting screen, they may wish to have a shorter nickname to appear when playing in a group. The second function is the ‘My Favorite Restaurants’ section. This allows users to see all their favorite restaurants in a quick and easy way. Users are allowed to initially bookmark these restaurants through the homepage restaurants screens and the results section of the gameplay screen.
Our software architecture starts with the User Mobile Device which communicates with Local asyncStorage to store user settings such as the toggle for never show again on the onboarding screen. The User Mobile Device also communicates with Google Authentication to display relevant login information and proceed with the authentication process. Google Authentication then contacts the Backend Server to complete necessary operations with the database. The Backend Server makes calls to the Yelp Fusion API to retrieve restaurant information and sends the information to the User’s Mobile Device so it can be appropriately displayed.
We used Google Authentication to handle the sign-in process and simplify it to prevent the need for a proprietary log-in system. Unfortunately, we started the development of Google Authentication with a deprecated React Native library which stalled progress for some time. After some research, we switched to using an expo package to handle Google Authentication which turned out to be a much better solution. Once we were able to successfully get user information from Google’s API, we made a POST call to our database to create an account with the necessary information.
We created a caching system for restaurant details, to limit the number of “GET” requests we made to the API. We defined a new database schema and set up various API endpoints to our express server to access this in our database. Every time we retrieved a basic list of restaurants from the Yelp API’s Business Search endpoint, before proceeding to get further details about each restaurant using the Business Details endpoint, we would first check our MongoDB to see if those details already exist or not for each restaurant and if they were updated recently enough (we chose this timeframe to be a week). If the details were in our “cache”, we would fetch those from our database instead of having to make another GET request to the Yelp API. This led to the next step as it was to make sure we were able to seamlessly integrate the backend with the actual frontend that the user would interact with. We defined backend controllers so that we could make calls to the APIs we created inside the different pages of the app.
Unit testing phases utilized the Jest testing framework to ensure that individual calls to the API worked correctly with isolated HTTP requests. After successful development iterations with unit testing, the backend would move to integration testing with the entire app by testing against certain app features such as accessing MongoDB databases and ensuring different API calls interacted correctly. Integration testing also ensured that the interfaces provided by each API were standardized to provide easier access calls.
We wrote code to pass information through screens of the Game Creation. Information was stored as values of an object, and this object was passed between screens. To pass values, we used props and the route parameter. When using the navigation component of React Native to move screens during the Game Creation, along with the name of the next screen — as declared in the StackNavigation, we also passed the information needed for the next screen to display. One of the most significant challenges related to information flow was initially giving them state with State Hooks. We realized that this approach was causing the screens to transition before any sort of changes were made to the object variables by the user. To overcome this, we were forced to assign the object given by the route to a constant variable on each screen.
One of the first UI components that we started to develop was the Gameplay Preferences/Setup and the Gameplay itself. Using the designs from the designer’s high-fidelity prototypes, we created the UI layout for the user to interact with. From here, the user was able to choose from the 3 pathways: create a new solo game, create a new group game, or join a game. The user is able to select which preferences they would like on each screen before being given a countdown timer to start the gameplay. In the gameplay UI, developing the food card that showed the image of the restaurant as well as the name, number of stars and reviews, distance, etc proved to be a challenge. We ended up extrapolating a generic card layout that accepted props to create the unique UI. These props included the image, restaurant name, number of reviews, distance, number of stars, and type of food/cuisine. This card layout was then used as a component in the main gameplay screens. Through this development, we were introduced to the use of flexbox in React Native, as well as the use of React Native components. Flexbox allowed us to more easily layout the components of our UI, and the use of components such as Pressables made using buttons more streamlined.
The next UI piece we tackled was the “Waiting to Join” page. This page was the kahoot-style waiting room for either leaders waiting for members to join or for those joining a game to wait for everyone else to join. This screen is conditionally rendered based on if the user is the group leader or not. The page for the group leader allows them to go back and recopy the game code to share. The images are rendered in rows of 4 with their names underneath. We created a component to display a single image with a name, that took both an image and a name as props. These components were conditionally rendered based on the number of people that had joined. This part of the development was the most complex, but we made use of functions in React Native that allow this type of functionality in regards to rendering something a certain number of times.
We then went to develop the “Gameplay Onboarding” page. The development of this page was mostly straightforward, but what was most complex was the sliding feature of the instructions. We ended up using a React Native component that was developed for this purpose and only needed to provide the actual view that goes inside each page of the slider. The “never show again” button is implemented to not show the user the onboarding pages again, and the small orange arrow is to skip the instructions. Through the development of this page, we practiced more with useState as well as page navigation.
The last main UI portion of the app that was developed was the profile page. This page receives the profile object once the user is signed in from the Google Authentication. Inside this profile object is the user’s name, as well as an array of favorite restaurants. These favorite restaurants are objects themselves, each with a name, image, and number of stars. We decided to make a component for a generic restaurant card that accepted these three props to build the unique UI layout. On the main profile page there are only 3, but selecting “See more” takes the user to the favorites page that has a scrollable list of the user’s favorite restaurants. One main challenge was getting the list on the favorites page to be scrollable, but we used React Native’s components to implement this feature. There is also an “Edit Profile” button that brings up a popup to allow the user to change their name. Once this is done, there is an API call to our backend to update the stored user name so they don’t have to repeatedly change it. Finally, there are the “Log Out” and “Delete Account” buttons that allow the user to either log out of their account or delete their account altogether.
Takeaways & Challenges
Challenge: Time Constraints
Due to time constraints and having to deal with exam schedules, we were forced to have to remove certain features, especially ones we thought were necessary in order to get a certain amount done by the deadline.
Challenge: Google Authentication
Since none of us have worked with a mobile application prior to Food-Off, Google Authentication took us a lot of time and pushed what we had on schedule quite a bit.
Challenge: API Work
Our API work continued to challenge us and give us issues and bugs but we slowly were able to adjust and figure it out.
In a team setting of 9 individuals, it was hard to figure out schedules and communicate thoroughly; especially getting weekly meetings with everyone attending. Furthermore, since we only met in person a few times a week, it made it hard to communicate what part everyone was on in their work since some overlapped.
Takeaway: Cross-Functional Environment
We got the chance to have developers work with designers and vice versa to understand how development works in the real world and it gave us an opportunity to realize how different parts of the team work.
Home Page Features
Some final home page features are left to take care of, for example, making sure the Yelp API is fully connected and integrated.
In order to officially launch and publish our app on the app store and such stores, we need to obtain a D-U-N-S number.
We were forced to scrap features due to time constraints but are aiming to implement a profile page, reviews page, animations throughout the app, and further expanding beyond Davis if possible at all.
Thank you to our project mentor and all of CodeLab for giving us the opportunity to work on such an amazing project with such great teammates. We got the chance to learn so much about all parts of a project and are extremely grateful for the experience.