Sprint 3 - EQUIPO-11-CONSTR-APLIC-MOVILES/Team-11-Wiki GitHub Wiki
- Implementation of the SendSearchedCategoriesEvent use case.
- Inclusion of the SendSearchedCategoriesEvent use case in SearchViewModel.
- Implementation of the SearchedCategoriesEvent in the SearchScreen.
- Creation of the SearchedCategoriesEvent in the SearchEvent.
- Creation of the SearchedCategoriesRepository and it's implementation.
- Inclusion of new elements in the DI app module.
- Re organizing use cases.
- Creation of the LikeDateRestaurantRepository interface and implementation.
- Creation of the SendLikeDateRestaurantEvent and its inclusion in the AnalyticsUseCases.
- Modification of HomeViewModel, HomeScreen, HomeEvent for measuring like events to a restaurant in a date.
- Inclusion of the new elements in the DI app module.
- Creation of the review list screen files ReviewListState, ReviewListViewModel, ReviewListScreen and ReviewListEvent.
- Creation of the ReviewsRepository interface and implementation.
- Creation of the GetRestaurantsReviews use case and the ReviewsUseCases class.
- Inclusion in the AppModule for DI.
- Implementation of StarPicker, ReviewListViewModel, ReviewListEvent, ReviewListScreen, ReviewListEvent.
- Modification of NoAction for the DynamicTopBar in reviews.
- Modification of restaurantCard for acting with its id and making of the necessary changes in HomeScreen, LikedScreen, RestaurantsLazyList and SearchScreen
- Generalization of Star and StarRating for reusabilitiy and modification of the CardMarker as a consequence.
- Addition of the ReviewListScreen route and include it in the NavGraph.
- Addition of the restaurantId, authorPFP and date field in the Review model class.
- Implementation of time spent on the ReviewListScreen
- Added loading circle and no reviews sign implementation in the ReviewListScreen, ReviewListState and ReviewListViewModel files.
- Fixing the star selector in ReviewListEvent, ReviewListScreen, ReviewListState and ReviewListViewModel.
- Uncommenting of the screen time measurement.
- Setting the option of defining colors for the stars in the StarRating composable.
- Merge with develop with the detail screen.
- Slight visual changes in starRating.
- Fixing visuals ReviewListScreen.
- Visual fixes in the map cards and redirection to detail.
- Configuration of the RandomScreen in the NavGraph.
- Creation of the RandomEvents
- Implementation of the RandomScreen and the RandomViewModel.
- Implementation of the time measurements in the detail screen.
- Implementation of the Connectivity State functions in NetworkState.kt.
- Added the HomeScreen generic fallback on connectivity failure.
- Inclusion of the connectivity logic in the HomeViewModel
- Factorization of the NoConnection item from HomeScreen.
- Simplification of the HomeViewModel
- Implementation of the eventual connectivity in the LikedScreen and LikedViewModel.
- Simplification of the LikedViewModel connectivity solution.
- Implementation of eventual connectivity in the ReviewListScreen, ReviewListViewModel and ReviewListState.
- Modifications to the CardMarker to show a default icon in case of no connectivity.
- Implementation of eventual connectivity in the MapScreen and MapViewModel.
- Fix of NetworkState bug on the MapScreen.
- Slight modification to the RestaurantCard, RestaurantsLazyList, HomeScreen, LikedScreen, HomeViewModel and LikedViewModel to reload images on network connectivity which was missing in previous commits.
- Inclusion of the retrofit library
- Creation of the AnalyticsAPI, AnalyticsRepository, AnalyticsRepositoryImpl.
- Respective modifications in the DI app module.
- Creation of the GetLikeReviewWeek
- Creation of GetFeaturedArray
- Inclusion of GetFeaturedArray in the RestaurantUseCases
- Inclusion of GetLikeReviewWeek in the AnalyticsUseCases.
- Modification of the HomeScreen, HomeState, HomeViewModel and RestaurantCard, RestaurantsLazyList for implementing the BQ's visualization.
- Creation of the RestaurantData DTO for the BQ's information.
- Addition of the percentage completion business question in the AnalyticsAPI, AnalyticsRepository, AnalyticsRepositoryImpl
- Creation of the GetPercentageCompletion and inclusion in the AnalyticsUseCases.
- Corresponding changes in the AppModule.
- Creation of the completion percentage in the HomeScreen, HomeViewModel and RestaurantsLazyList.
- Writing of eventual connectivity scenarios
- Writing of the kotlin concurrency strategy
- Writing of the kotlin cache strategy
- Changes in MapScreen, MapViewModel and NavGraph to create a shared viewmodel across all map screen stack entries.
- Participation in the ethics video.
- Implemented write review screen
- Implemented eventual connectivity strategies for Log In and Register Screen
- Implemented reviewed percentage business question
- Implemented featured restaurants business question
- Documented multi-threading strategy for flutter
- Documented eventual connectivity scenarios for Log In Screen, Register Screen, and Write Review Screen
- Implemented caching strategy for loading images in flutter
- Implemented random restaurant screen
- Implemented review list screen
- Implemented eventual connectivity strategies for Map Screen
- Implemented business question: How often does a user leave a review after using the "randomize restaurant" feature?
- Fixed restaurant-cuisined based recomendations business question
- Connected the map screen with the restaurant detail screen
- Documented caching strategy for flutter
- Documented eventual connectivity scenarios for Map Screen, Review List Screen, Random restaurant Screen
- Implemented write review screen in Kotlin
- Implemented eventual connectivity strategies for Search Screen
- Implemented eventual connectivity strategies for Random Restaurant Screen
- Implemented eventual connectivity strategies for Write Review Screen
- Implemented local storage strategy for recent restaurants in Kotlin
- Documented local storage strategy for Kotlin
- Documented eventual connectivity scenarios for Write review Screen and Search Screen
- Implemented the BQ: In what area are the restaurants that are the most liked?
- Creation of the graphs in the dashboard for the BQ about the area with the most liked restaurants.
- Help in the implementation of the BQ: What is the number of users per device model?
- Restaurant detail screen
- Schedule pop up
- Eventual Connectivity Strategies for Sign In, Sign Up and Restaurant Detail
- Ethics video participation
- Documented eventual connectivity scenarios for Sign In, Sign Up and Restaurant Detail
- Implemented changes in kotlin for business question: How often does a user leave a review after using the "randomize restaurant" feature?
- Implemented business question: "What common qualities are shared by the restaurants most frequently added to users' favorites?"
- Restaurant detail screen
- Eventual connectivity for restaurant list, search screen and restaurant detail
- Ethics video section
- Local storage strategy implementation in flutter
-
Use the phone's microphone to listen the users voice to fill the search field with their words when searching for restaurants in the search screen.
-
In the map screen, the map shows with a special icon the location of a restaurant that is within a radius of the user if it is new, if the user hasn't liked it yet and if any of the restaurant's categories is within the user's liked categories.
-
Depending on the location of the user and the established search radius, it will automatically adapt and show the restaurants near the user.
-
Section in the home screen that recommends the user restaurants he/she might like and improve their experience through the highlighting of restaurants that match their registered likings in the app.
-
Login and register screen for the users to enter or create an account that stores their liked restaurants and authentication details.
-
Use the google maps code API and the google play map services to show the user the locations of restaurants near them, in addition to their surroundings and points of interests.
-
Firebase database for persisting the user's, information, restaurant's information, analytics events and information needed for the functioning of the application. This service is used to track the users likes, liked categories, list the restaurants, filter them and find their location.
-
Firebase storage to store image files for the images that belong to restaurants and the images that are assigned to represent the users.
-
List of currently opened restaurants that uses the phone's time and compares this value with the schedules of the restaurants.
-
List of all restaurants.
-
Screen that allows the user to find restaurants using keywords, see the restaurants he recently searched for and erase their history.
-
List of liked restaurants by the user.
-
Specialized restaurant screen that displays the restaurant's details
-
Review list for each restarant that shows a score and description left other users
-
The option to write a review for a restaurant, leaving a description and a star rating
-
A random restaurant screen, that displays the details of one of the restaurants in the database
Type 1: What is the number of users per device model?
Type 2: What restaurant(s) have been the most liked or positively reviewed this week?
Type 2: What percentage of the restaurants has the user left a review in?
Type 3: How often does a user leave a review after using the "randomize restaurant" feature?
Type 4: What common qualities are shared by the restaurants most frequently added to users' favorites?
Type 5: In what area are the restaurants that are the most liked?
Event Description | The user wants to sign in but has no internet connection. |
---|---|
System Response | The system will notify the user to sign-in later with connection. |
Possible Antipatterns | #1 Blocked Application, #3 Non-informative message |
Caching + Retrieving Strategy | N/A |
Storage Type | N/A |
Stored Data Type | N/A |
Rationale | Signing in requires real-time server authentication to validate user credentials, making an internet connection essential. To prevent user frustration from unsuccessful attempts, the system promptly informs the user to try again when online. This clear messaging reduces confusion and ensures data security, as caching sign-in credentials without connectivity could risk incomplete authentication and user privacy. |
Event Description | The user wants to sign in and looses connectivity while the app is checking their credentials. |
---|---|
System Response | The system will notify the user there was an error connecting to the server. |
Possible Antipatterns | #1 Blocked Application, #3 Non-informative message |
Caching + Retrieving Strategy | N/A |
Storage Type | N/A |
Stored Data Type | N/A |
Rationale | Since sign-in relies on live server access to verify credentials, a sudden loss of connectivity prevents the app from completing the authentication. By clearly notifying the user of the connectivity issue, the app avoids confusion and sets expectations for retrying the action. This approach improves the user experience by providing specific information about the error and reducing the frustration of unclear or stalled processes. |
Event Description | The user wants to sign up but has no internet connection. |
---|---|
System Response | The system will notify the user to sign-up later with connection. |
Possible Antipatterns | #1 Blocked Application, #3 Non-informative message |
Caching + Retrieving Strategy | N/A |
Storage Type | N/A |
Stored Data Type | N/A |
Rationale | Since sign-up is a one-time action that requires a stable connection to authenticate and save the user’s data, it’s essential that it occurs online. Without internet access, the system avoids caching any data to prevent incomplete or failed sign-up attempts. Instead, it promptly informs the user to retry with an internet connection, which helps avoid confusion and ensures a smooth onboarding process when connectivity is available. |
Event Description | The user signed up successfully but looses internet access in the preferences screen |
---|---|
System Response | The system will set the preferences through the modification of the cached values. When recovering connectivity, it will commit and pull changes. |
Possible Antipatterns | #4 Lost content (Lost functionality) |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response |
Storage Type | 1.e. Firestore cache |
Stored Data Type | User Document |
Event Description | The user wants to see the restaurant lists in the homescreen but has no internet connection. |
---|---|
System Response | The system will still show the restaurant lists but using old locally saved data. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache, Coil library's memory and disk cache. |
Stored Data Type | Restaurant Documents, User Document, Image files |
Rationale | Given that the restaurant list is unlikely to change and the information rarely expires, it is logical to show this public-locally saved data for the user when there is no connectivity. |
Event Description | The user wants to see the restaurant lists in the homescreen for the first time but has no internet connection. |
---|---|
System Response | The system will show a message indicating that the user should connect to the internet to initiate their experience with the app. |
Possible Antipatterns | #2 Stuck progress bar, #4 Lost content, #3 Non-informative message |
Caching + Retrieving Strategy | #6 Generic fallback |
Storage Type | 1.d. App's stored files with texts and icons. |
Stored Data Type | Strings and XML |
Rationale | In this case, a message will be shown to the user given that there is no locally saved data, which makes it impossible to show content, however, a friendly message with a solution will be showcased. |
Event Description | The user wants to see the restaurant lists in the homescreen for the first time but has no internet connection, a generic fallback is shown but then the device recovers connection. |
---|---|
System Response | The system will reload the screen when detecting connectivity. |
Possible Antipatterns | #7 Unavailable functionality after connection recovery |
Caching + Retrieving Strategy | #2 Network only |
Storage Type | 1.e. Firestore NoSQL Document DB, Firebase Storage file system |
Stored Data Type | Restaurant Documents, User Document, Image files |
Rationale | When the device recovers connection, the screen reloaded because the user already solved the problem, so the information should be shown, else, the user will think there are more problems and that the app isn't properly handling them. |
Event Description | The user wants to see a random restaurant with no connection. |
---|---|
System Response | The system will still show a random restaurant but using old locally saved data. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache, Coil library's memory and disk cache. |
Stored Data Type | Restaurant Documents, User Document, Image files |
Rationale | As with the homescreen, given that there is locally saved data and that restaurant's information rarely expires or changes, it will be valid to show locally saved information to allow the user to have an offline experience. |
Event Description | The user opens the app for the first time and wants to see a random restaurant with no connection. |
---|---|
System Response | The system will show a generic fallback to notify the solution to the problem |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #6 Generic fallback |
Storage Type | 1.d. App's stored files with texts and icons. |
Stored Data Type | Strings and XML |
Rationale | Given that there is no locally saved information because it is the first time opening the app, a friendly message will shown with the solution to the problem. There is no way of showing the user the desired content in this point. |
Event Description | The user wants to see a random restaurant for the first time but has no internet connection, a generic fallback is shown but then the device recovers connection. |
---|---|
System Response | The system will reload the screen when detecting connectivity. |
Possible Antipatterns | #7 Unavailable functionality after connection recovery |
Caching + Retrieving Strategy | #2 Network only |
Storage Type | 1.e. Firestore NoSQL Document DB, Firebase Storage file system |
Stored Data Type | Restaurant Documents, User Document, Image files |
Rationale | The system needs to recover the functionality after the network is recovered, else it will seem like the suggestion we gave the user in the fallback was invalid. |
Event Description | The user wants to search for a restaurant by name or category in the Search Screen but does not have an internet connection. |
---|---|
System Response | The system will still show the filter restaurants when the users type in the input but using old locally saved data. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache, Coil library's memory and disk cache. |
Stored Data Type | Restaurant Documents, User Document, Image files |
Rationale | Given that the restaurant list (to filter, all the restaurant list is needed) is unlikely to change and the information rarely expires, it is logical to show this public-locally saved data for the user when there is no connectivity. |
Event Description | The user wants to search for a restaurant by name or category in the Search Screen for the first time but has no internet connection. |
---|---|
System Response | The system will show a message indicating that the user should connect to the internet to initiate their experience with the app. |
Possible Antipatterns | #2 Stuck progress bar, #4 Lost content, #3 Non-informative message |
Caching + Retrieving Strategy | #6 Generic fallback |
Storage Type | 1.d. App's stored files with texts and icons. |
Stored Data Type | Strings and XML |
Rationale | In this case, a message will be shown to the user given that there is no locally saved data, which makes it impossible to show content, however, a friendly message with a solution will be showcased. |
Event Description | The user wants to search for a restaurant by name or category in the Search Screen for the first time but has no internet connection, a generic fallback is shown but then the device recovers connection. |
---|---|
System Response | The system will reload the screen when detecting connectivity. |
Possible Antipatterns | #7 Unavailable functionality after connection recovery |
Caching + Retrieving Strategy | #2 Network only |
Storage Type | 1.e. Firestore NoSQL Document DB, Firebase Storage file system |
Stored Data Type | Restaurant Documents, User Document, Image files |
Rationale | When the device recovers connection, the screen reloaded because the user already solved the problem, so the information should be shown, else, the user will think there are more problems and that the app isn't properly handling them. |
Event Description | The user wants to see the liked restaurants list but has no internet connection. |
---|---|
System Response | The system will still show the liked list but using old locally saved data. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache, Coil library's memory and disk cache |
Stored Data Type | Restaurant Documents, User Document, Image files |
Rationale | The liked list is shown without connection given that, when there is no connection, there is a cache of data, so any changes to the list (additions or deletions) will be reflected in cache and then synchronized with the remote firestore server. |
Event Description | The user wants to see the liked restaurants list when opening the app for the first time but has no internet connection. |
---|---|
System Response | The system will show a generic fallback indicating that the user should connect to the internet to see the content |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #6 Generic fallback |
Storage Type | 1.d. App's stored files with texts and icons. |
Stored Data Type | Strings and XML |
Rationale | At this point, data has not been retrieved, so there is no way to show the user content, that's why a helpful message with the solution is shown. |
Event Description | The user wants to see the liked restaurant list for the first time but has no internet connection, a generic fallback is shown but then the device recovers connection. |
---|---|
System Response | The system will reload the screen when detecting connectivity. |
Possible Antipatterns | #7 Unavailable functionality after connection recovery |
Caching + Retrieving Strategy | #2 Network only |
Storage Type | 1.e. Firestore NoSQL Document DB, Firebase Storage file system |
Stored Data Type | Restaurant Documents, User Document, Image files |
Rationale | Even without closing the app, it needs to show the liked restaurants list when recovering connectivity, else it will seem like the app gave a wrong solution to the problem. |
Event Description | The user wants to see the reviews of a restaurant but has no internet connection. |
---|---|
System Response | The system will still show the reviews but using old locally saved data. |
Possible Antipatterns | #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache, Coil library's memory and disk cache. |
Stored Data Type | Review Document, Image files |
Rationale | If a user has previously seen a reviews restaurant, he will be able to see them offline due to the cached data, this will let the user still gain insight of the restaurants' quality even when offline. |
Event Description | The user wants to see the reviews list of a restaurant for the first time but has no internet connection. |
---|---|
System Response | The system will show a generic fallback indicating that the user should connect to the internet to see the content |
Possible Antipatterns | #3 Non-informative message |
Caching + Retrieving Strategy | #6 Generic fallback |
Storage Type | 1.d. App's stored files with texts and icons. |
Stored Data Type | Strings and XML |
Rationale | There is no other solution other than telling the problem with internet connection to the user when there is no saved data and the user is currently offline. |
Event Description | The user wants to see the review list of a restaurant for the first time but has no internet connection, a generic fallback is shown but then the device recovers connection. |
---|---|
System Response | The system will reload the screen when detecting connectivity. |
Possible Antipatterns | #7 Unavailable functionality after connection recovery |
Caching + Retrieving Strategy | #2 Network only |
Storage Type | 1.e. Firestore NoSQL Document DB, Firebase Storage file system |
Stored Data Type | Review Document, Image files |
Rationale | When the user solves the connectivity issue, the user should get the desired service, else the app would no be complying with it's purpose. |
Event Description | The user wants to create a Review but does not have an internet connection. |
---|---|
System Response | The system will display a message and save the review in the Firebase cache so the user does not lose the review they wrote. The review will be saved automatically once the internet connection is restored. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache. |
Stored Data Type | Reviews Documents, User Document, Image files |
Rationale | For the user, it would be very frustrating if, after writing the review, it wasn’t saved due to an internet issue. This is why this strategy is used. Additionally, a clear and friendly message is displayed to inform the user that there is no connection, but their review will be saved and sent once the connection is restored. |
Event Description | The user wants to create a Review but does not have an internet connection and closes the app. |
---|---|
System Response | The system will display a message and save the review in the Firebase cache so the user does not lose the review they wrote. The review will be saved automatically once the internet connection is restored, even if they close the app. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache. |
Stored Data Type | Reviews Documents, User Document, Image files |
Rationale | When the user, after writing the review and seeing the message that there is no internet and that their review will be sent once the connection is restored, regains connection, they might close the app. Therefore, the review cannot be lost under any circumstances. By using the Firebase cache, even if the app is closed, the review will be stored in the cache and will be sent once the connection is restored. |
Event Description | The user wants to see a restaurant detail but has no internet connection. |
---|---|
System Response | The system will still show the restaurant detail but using old locally saved data. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache, Coil library's memory and disk cache. |
Stored Data Type | Restaurant Documents, User Document, Image files |
Rationale | Given that the restaurant detail is unlikely to change and the information rarely expires, it is logical to show this public-locally saved data for the user when there is no connectivity. |
Event Description | The user wants to like a restaurant but has no internet connection. |
---|---|
System Response | The system will like the restaurants through the modification of the cached values. When recovering connectivity, it will commit and pull changes. |
Possible Antipatterns | #4 Lost content (Lost functionality) |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response |
Storage Type | 1.e. Firestore cache |
Stored Data Type | Restaurant Documents, User Document |
Event Description | The user wants to see the restaurant location on google maps but has no connection. |
---|---|
System Response | The system will still show a toast message explaining the user cannot be redirected due to no connection. |
Possible Antipatterns | #6 Redirection without connectivity check |
Caching + Retrieving Strategy | N/A |
Storage Type | N/A |
Stored Data Type | N/A |
Rationale | Displaying a clear message about the lack of connectivity ensures that the user understands why they cannot access the map. Without this message, the user might assume a technical issue rather than a connectivity problem. This approach improves user experience by preventing failed redirection attempts and providing feedback that explains the need for internet access to view location details on Google Maps. |
Event Description | The user is in the map screen but has no internet connection. |
---|---|
System Response | The system will still show the map and restaurants but using old locally saved data. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response |
Storage Type | 1.e. Firestore cache, Google Maps cache, 1.d. Image files |
Stored Data Type | Map file, Restaurant Documents, Image files |
Rationale | If the user is currently in the map, the map information is displayed along with the location of the user, the restaurants and the images the user visited previously. It's logical to keep the information and let the user still use it even though he/she can't load more images or change the location. He/She will be able to use the functionality with the last known location. |
Event Description | The user wants to see the map but has the phone's location feature unavailable. |
---|---|
System Response | The system will show a generic fallback mentioning that the user needs to have the location feature available to work properly. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar |
Caching + Retrieving Strategy | #6 Generic fallback |
Storage Type | 1.d. App's stored files with texts and icons. |
Stored Data Type | Strings and XML |
Rationale | If the user hasn't entered the map, there will be no location loaded. Consequently, the map won't be able to set the information on the nearby restaurants, the functionality would loose it's purpose, that's why a message is shown to the user with a solution. |
Event Description | The user wants to see the map but has no internet connection. |
---|---|
System Response | The system will show a message indicating that the user should connect to the internet to initiate their experience with the app. |
Possible Antipatterns | #4 Lost content |
Caching + Retrieving Strategy | #6 Generic fallback |
Storage Type | 1.d. App's stored files with texts and icons. |
Stored Data Type | Strings and XML |
Rationale | If the user wants to see the map but has no connection, he won't be able to see it because internet is needed for loading the map. If there is no connectivity, the map would be blank and fall on the lost content (map) antipattern, that's why a message with a solution to the problem will be shown. |
Event Description | The user wants to see the restaurant lists in the homescreen but lacks internet connection. |
---|---|
System Response | The system will still show the restaurant listsusing the last locally saved data. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache. |
Stored Data Type | Restaurant Documents |
Rationale | Since the restaurant list is unlikely to change frequently and the data rarely expires, it makes sense to display this publicly stored local data to the user when there is no connectivity. |
Event Description | The user wants to see a random restaurant but has no internet connection. |
---|---|
System Response | If restaurants have been previously loaded, the system will show a random restaurant using the last locally saved data. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache. |
Stored Data Type | Restaurant Documents |
Rationale | Since the restaurant list is unlikely to change frequently and the data rarely expires, it makes sense to display this publicly stored local data to the user when there is no connectivity. |
Event Description | The user wants to see the reviews of a restaurant but lacks internet connection. |
---|---|
System Response | The system will still show the reviews using the last locally saved data. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache. |
Stored Data Type | Review Documents |
Rationale | Since the reviews are unlikely to change frequently and the data rarely expires, it makes sense to display this publicly stored local data to the user when there is no connectivity. |
Event Description | The user liked a restaurant but lacks internet connection. |
---|---|
System Response | The system will update restaurant preferences by modifying cached values, as soon as connectivity is restored, it will synchronize the changes. |
Possible Antipatterns | #4 Lost content |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response |
Storage Type | 1.e. Firestore cache |
Stored Data Type | Restaurant Documents, User Document |
Rationale | Since the likes are saved in the user document and this is stored in the Firestore, that requieres connection to retrieve data, to avoid the loss of content we save the liked restaurant in the cache record and then, when connection is restored, we commit it to the backlog store. |
Event Description | The user wants to access the restaurant location but lacks internet connection. |
---|---|
System Response | The system will notify the users that the device is not connected to internet so they shall try later. |
Possible Antipatterns | #6 Redirection without connectivity check |
Caching + Retrieving Strategy | #2 Network only |
Storage Type | N/A |
Stored Data Type | N/A |
Rationale | Since the location is feature managed by the Google Maps application, it needs full time connection in order to fetch and retrieve the location by the coordinates passed by parameter. To avoid redirection without connectivity we deny the access to the user to this feature and suggest him to get connected to internet. |
Event Description | The user is on the map screen but has no internet connection. |
---|---|
System Response | The system will display a screen stating "Internet connection is required to use the map" to inform the user of the connectivity need. |
Possible Antipatterns | #4 Lost content, #2 Stuck progress bar |
Caching + Retrieving Strategy | #6 Generic fallback |
Storage Type | N/A |
Stored Data Type | N/A |
Rationale | Since the map functionality requires real-time connectivity to retrieve restaurants, the system will avoid showing an incomplete or non-functional map by displaying a clear message to the user. This avoids the lost content antipattern by informing the user that the map is not usable offline. |
Event Description | The user is on the map screen, had no internet connection, but later got connection. |
---|---|
System Response | The system will reload the map and display the restaurants once the connection is restored. |
Possible Antipatterns | #7 Unavailable functionality after connection recovery |
Caching + Retrieving Strategy | #2 Network only |
Storage Type | N/A |
Stored Data Type | N/A |
Rationale | When the device regains connectivity, the map should reload to show the updated information, ensuring the user gets the desired service. |
Event Description | The user wants to send a review but has no internet connection. |
---|---|
System Response | The system will save the review in cache and send it once it establishes an internet connection, a message will be shown indicating that the review was saved and will be sent when internet access is regained. |
Possible Antipatterns | #2 Stuck Progress Notification, #3 Non-informative message, #4 Non-existent response notification, #5 Unavailable Functionality after Connection Recovery |
Caching + Retrieving Strategy | #3 Network falling back on cache |
Storage Type | 3.e Firebase cache |
Stored Data Type | Review Document |
Rationale | This strategy is appropriate because it allows the user to write and send a review while offline. |
Event Description | The user wants to search a restaurant but has no internet connection. |
---|---|
System Response | The system will still show the restaurant that match the search query but using old locally saved data. |
Possible Antipatterns | #4 Lost content, #3 Non-informative message |
Caching + Retrieving Strategy | #3 Network falling back to cache, #4 Cached on network response, #1 Cache falling back to network |
Storage Type | 1.e. Firestore cache. |
Stored Data Type | Restaurant Documents |
Rationale | The search procedure will be executed over the restaurants list saved in the cache storage. |
Event Description | The user wants to log in but has no internet connection. |
---|---|
System Response | The system will show a message indicating that to log in they must connect to the internet. |
Possible Antipatterns | #2 Stuck Progress Notification, #3 Non-informative message, #4 Non-existent response notification, #5 Unavailable Functionality after Connection Recovery |
Caching + Retrieving Strategy | #2 Network only |
Storage Type | N/A |
Stored Data Type | User Document |
Rationale | This strategy is appropriate because a user shouldn't be able to log in without accessing the authentication services. |
Event Description | The user wants to register but has no internet connection. |
---|---|
System Response | The system will show a message indicating that to register they must connect to the internet. |
Possible Antipatterns | #2 Stuck Progress Notification, #3 Non-informative message, #4 Non-existent response notification, #5 Unavailable Functionality after Connection Recovery |
Caching + Retrieving Strategy | #2 Network only |
Storage Type | N/A |
Stored Data Type | User Document |
Rationale | This strategy is appropriate because a user shouldn't be able to register without accessing the authentication services. |
Event Description | The user registers email and password, loses connection and registers preferences |
---|---|
System Response | The system will store the preferences in cache and send them once the device regains connection, the user will be transported to the log in screen. |
Possible Antipatterns | #2 Stuck Progress Notification, #3 Non-informative message, #4 Non-existent response notification, #5 Unavailable Functionality after Connection Recovery |
Caching + Retrieving Strategy | #3 Network falling back on cache |
Storage Type | 3.e Firebase cache |
Stored Data Type | User Document |
Rationale | This strategy is appropriate because if the registry credentials have already been checked as valid, the user should be able to continue the register process even if offline. |
In RestaU, DataStore is used as a local storage strategy to save recently visited restaurants. DataStore is ideal for handling small datasets asynchronously and securely, improving concurrency and access compared to alternatives like SharedPreferences.

The implementation centers around the RecentsRepository interface, which defines two main methods: saveRecentsEntry, to store a set of restaurants, and readRecentsEntry, which returns a reactive data flow (Flow) of these entries. Since DataStore only supports key-value pairs, the Restaurant objects are serialized to JSON with Gson before storing and deserialized when reading. This approach efficiently manages complex objects like Restaurant.
override suspend fun saveRecentsEntry(recents: Set<Restaurant>) {
val json = gson.toJson(recents)
context.datastore.edit { settings ->
settings[PreferenceKeys.RECENTS_ENTRY] = json
}
}
override fun readRecentsEntry(): Flow<Set<Restaurant>> {
return context.datastore.data.map { preferences ->
val json = preferences[PreferenceKeys.RECENTS_ENTRY] ?: ""
if (json.isNotEmpty()) {
val type = object : TypeToken<Set<Restaurant>>() {}.type
gson.fromJson(json, type)
} else {
emptySet()
}
}
}
A unique key (RECENTS_ENTRY) is defined in PreferenceKeys to identify recent restaurant data. This key ensures unique storage in DataStore, avoiding access conflicts. The Context.datastore extension enables DataStore to be accessible throughout the app via context, standardizing usage and simplifying data management.
private object PreferenceKeys {
val RECENTS_ENTRY = stringPreferencesKey(Constants.RECENTS_ENTRY)
}
DataStore was chosen over a local database like Room due to its lightweight nature and efficiency for handling small, key-value-based datasets, such as recently visited restaurants. Unlike Room, which is better suited for more complex, relational data structures, DataStore offers simpler setup and faster access for small data without the need for complex querying. Additionally, DataStore integrates seamlessly with Kotlin coroutines and flows, making it ideal for reactive and asynchronous data handling, which enhances performance and responsiveness in the app's user experience.
In the Flutter implementation of RestaU the local storage strategy is applied through the shared preferences APIS. SharedPreferences is a simple key-value storage for saving small amounts of data locally on the user's device. It's commonly used for storing user preferences, settings, and other small pieces of persistent data that should be retained across app sessions.
The main application of this strategy is in the Search feature for saving the recent searches for restaurants of the user. To do so, the search_viewmodel class define a couple of functions that manage this local storing mechanism. The first one this saveLastSearchResults() that after loading and parsing the [SharedPreferences] for the app from disk. Saves a list of strings, represented a list of each id from the lasSearched restaurants by the user to persistent storage in the background. We can appreciate the implementation as following:
Future<void> _saveLastSearchResults() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> idList = _lastSearchResults.map((restaurant) {
return restaurant.id.toString();
}).toList();
await prefs.setStringList('lastSearchResults', idList);
}
The second function is the related to loading the last search results from the persistent storage, this instruction retrieves a list of ids belonging to the last searched restaurants and then passed as argument to the function that fetch a restaurant by its id to retrieve a Restaurant object.
// Cargar resultados recientes desde SharedPreferences
Future<void> _loadLastSearchResults() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String>? idList = prefs.getStringList('lastSearchResults');
if (idList != null) {
// Assuming you have a method to fetch restaurant by id
_lastSearchResults = await Future.wait(idList.map((id) async {
return await fetchRestaurantById(id);
}).toList());
} else {
_lastSearchResults = [];
}
notifyListeners();
}
The kotlin app uses 2 concurrency strategies, multithreading and coroutines. Coroutines are blocks of code that run concurrently, which avoids blocking the main thread. However, they are also not bound to any thread, which allows developers to delegate them or parts of them to other threads and take advantage of the benefits of multithreading. Android/Kotlin has 3 threads where coroutines can be delegated, the Main
thread which is in charge of painting the UI and managing user and external events, the IO
thread which is optimized for actions such as network calls or retrieving information from the disk, and the Default
thread which is a heavy thread for long running tasks. We can change coroutines from threads by using the Dispatchers
class in the coroutine creator launch
function. By using all this previously mentioned concepts, we can improve performance significantly and develop tasks concurrently.
In the following image, the sendEvent
function creates a coroutine in the IO thread.
In the changeCircleRadius
function, the method creates a coroutine in the Default thread.
In the following image, the launch
function is changed for the async
method. The async method is a coroutine that returns a defered object, that will adquire a success or failure value in a point forward in time like promises in javascript.
In all the examples, it can be seen the viewModelScope
object which ties all the coroutines to the view model's lifecycle.
The Flutter application uses Futures as its multithreading/concurrency strategy. Futures allow the app to continue its main process while another process happens simultaneously.
In the example above, we use the FutureBuilder to build the list of all restaurants. As these are fetched from Firebase and this process takes time, the use of Futures allows the page to load while the restaurants are being retrieved, displaying them as soon as they become available.
The function for retrieving all restaurants returns a Future list of restaurants, which will be used to load the list.
As a cache strategy, we decided to use a hashmap to store the bitmaps that were retrieved from the network when showing a restaurant's card when clicking a pin in the map. When pressing a pin, if an image is not in the hashmap contained in the state, it is retrieved from the remote firebase storage, if it is, it is simply shown to the user. With this bitmap hashmap, the user will experience less delays when opening a card and observing the related image and resources for making network requests saved, instead of making constant calls to the remote server. This cache is persistent per session given that it is a memory cache stored in the map's view model, when the viewmodel is disposed, this cache will be cleared.
The previous image illustrates the process where in line 194, the cache is checked if the image is already stored, if it isn't, asynchronically (line 195 with the launch method) in line 196, the image is downloaded and saved in the state (lines 197-201) to be shown in the screen when the pin is clicked.
The caching strategy involves saving images of restaurants using the cached_network_image
package, which leverages local storage to keep downloaded images accessible offline. When an image is requested, it checks for a local copy of the restaurant image; if available, it serves the cached version, reducing redundant network calls and enhancing load speeds. If a cached copy does not exist, the image is downloaded, displayed, and stored in cache for future use. This setup is optimized for offline accessibility and efficient loading, reducing network usage for frequently requested restaurant images.
This can be seen in the following code:
class CustomCacheManager extends BaseCacheManager {
static const key = "customCache";
CustomCacheManager()
: super(
key,
maxAgeCacheObject: Duration(days: 7),
maxNrOfCacheObjects: 100,
);
}
This class creates a cache manager that will store up to 100 images for a maximum of 7 days.
CachedNetworkImage(
imageUrl: restaurant['imageUrl'],
cacheManager: CustomCacheManager(),
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
)
This code snippet displays the image, first checking if it’s in cache; if not, it retrieves the image from imageUrl
or shows a circular progress indicator while loading.
This approach significantly improves restaurant image loading times, allowing the app to handle high-frequency image requests with reduced latency and less network dependency.