[toc]
UID | Name | Role |
---|---|---|
u7233149 | Kai Hirota | Full-Stack |
u7269158 | John (Min Jae) Kim | Data Structure, Feature Testing |
u7234659 | Honggic Oh | Search, Feature Testing |
u7199021 | Theo Darmawan | Full-Stack |
Targets Users: Workout Enthusiasts
Route42 is a social networking app for athletes of various levels. With Route42, users can:
- Record workouts, including walking, running, and cycling.
- Track performance metrics and see the recorded workouts in an interactive map.
- Follow other users, and view and like other people's workouts.
- Search for posts by username, hashtags, and proximity to the user's location
Image: Feed, Activity logging, Profile, Route, and Nearest Neighbor Search screens (Left to Right)
-
Athletic Activity Tracking and Sharing
- Michael runs at ANU running club, and wants to record and share his daily runs.
- Once ready, he starts the
run
activity on the app
- The app tracks Michael's location and route, and display it on a map. Performance metrics are displayed in real time.
- After finishing his run, Michael ends the
run
activity on the app. - The app will display a post template for sharing the completed activity.
- Michael may write a description and add hashtags like
#ANUrunning
before sharing it. The app will extract the hashtags and tag the post for you. - The created post can immediately be viewed by other users on their feeds.
- Michael can also select his past posts or posts created by others and see an interactive map of the route associated with the post.
-
Social networking and searching
- Emily is an avid runner who recently started competing in marathons. Emily wants to connect with other aspiring athletes.
- Emily can search for posts on Route42 app by username and hashtags, and look at other athletes and their workouts and routes.
- Emily can also search for posts by geographical proximity, and the app will visualize the places where others logged their workouts on an interactive map.
If the user does not have an active internet connection, the app allows scheduling of posts and
likes. To schedule a post, the user checks the schedule
button and selects the time delay. To
schedule a like, the user long-clicks the like button and selects the time delay.
If the user needs to pause the workout, they can manually do so. Otherwise, navigating away from
the Activity
screen will automatically pause it for them.
- KD Tree
- Where: REST API
GET /search/knn
withk
,lon
,lat
parameters. - Why: KD Tree (K-dimensional tree) is used to store and search 2-D data of location (longitude, latitude). KD tree is useful for finding nearest neighbors and performing range search based on multiple dimensions of data - such as longitude and latitude.
- Where: REST API
- HashMap
- Where: Used by the REST API for union and intersection operations between lists of
Post
s. - Why: It's the most efficient way of finding set union and intersections. This is used to chain
the left and right results when executing commands in
QuerySyntaxTree
.
- Where: Used by the REST API for union and intersection operations between lists of
- Binary Tree
- Where:
- REST API
POST /search/
endpoint usesQuerySyntaxTree
to process the query text sent by a client. QueryTreeNode
is used to extract the hierarchical structure of nodes, each representing a binary operator and two expressions.
- REST API
- Why:
- It allows efficient parsing of tokens, and allows us to express various operations in a recursive manner, making the code easy to read and maintain.
- Where:
-
Singleton & Repository
- Where:
UserRepository
andPostRepository
classes underrepository
submodule. - Why:
- Singleton pattern prevents unnecessary creation of multiple instances of connections with the database. By using singleton, the program uses less memory, and managing the connection with the database is easier.
- Repository pattern abstracts the database operations and allows decoupling of the database access logic from the application logic.
- Where:
-
Single-activity architecture
-
-
What: Composition of Android application based on single or a couple activities, each managing one or more fragments.
-
Where: Entire application.
-
Why:
- Route42 primarily has one activity called
MainActivity
which contains a fragment container view, which swaps between fragments based on user interactions. - Usage of this architecture reduces lines of code required for the whole app, while making it easier to prototype new features.
- Route42 primarily has one activity called
-
-
REST API
- Where: In the cloud (AWS EC2 instance)
- Why:
- When using Cloud Firestore Android SDK, we have some limitations.
- Cannot perform partial text search - for example, we cannot query on substring of a text field.
- Cannot use more than one
arrayContains
in a single query. - No support for boolean OR operation between multiple filters.
- Every CRUD operation must be asynchronous in order to not freeze up the UI thread.
- Using the REST API allows us to use the Firebase-admin SDK, which gives the REST API higher privilege and more capability than the mobile client.
- Using REST API allows us to simplify database reads and writes. The downside is that we sacrifice Firestore's document listener feature, where we can listen to updates on documents of interest.
- When using Cloud Firestore Android SDK, we have some limitations.
-
ViewModel
- What: An intermediate observable class which enables data to persist independent of fragment lifecycle and attaching listeners to data changes.
- Where:
ActiveMapViewModel
andUserViewModel
- Why: By storing data in a view model class, data is not deleted when views are destroyed (e.g.
when the user navigates to another page, or when the phone is rotated). Also, by listening to
changes to
LiveData
members of the view model, views can update directly to changes in persistent data stored in Firebase, through listening to theLiveData
class. This improves separation of UI layer from the data layer, as the UI is not dependent on any repository classes.
-
Multi-threading / background execution
- Where:
PhotoMapFragment
,ScheduleablePost
,SchedulableLike
- Why: When making the REST API call to
search/knn
, the communication is handled by a background worker thread. This ensures the UI thread (the main thread) does not freeze and remains responsive. Scheduled actions involving IO operations and network calls are also handled in the background to minimize load on the UI thread.
- Where:
<Term> ::= <Expr> | <Term> + <Term> | <Term> + <Operator>
<Expr> ::= <Keyword> | <bracket>
<Operator> ::= <and> | <or>
Advantage
- Parser Tree is a binary tree as opposed to being a n-ary tree, making it easier to construct the Parser Tree.
Disadvantage
- When multiple AND / OR operations are used in the query (
i.e.
"hashtag: #running AND hashtag: #jogging"
), Parser Tree does not make optimizations. While Firestore supports.arrayContains()
operation, our Parser Tree represent eachAND/OR
as a single node. In other words,"hashtag: #running AND hashtag: #jogging"
could be represented as a single node in an n-ary tree, but
- Every token either contains an operator and two expressions, or a key and value.
- Tokens are extracted by prioritizing parenthesis, and then extracting from left to right.
- For example, if a query consists of 10 hashtags chained by OR, then the
resulting
QuerySyntaxTree
will be equivalent to a linked list, where each node only has a right child.
Examples
1. "test test2" -> {hashtags: ["test", "test2"]} ->
Node(
Node(null, "hashtags:test", null),
OR,
Node(null, "hashtags:test2", null)
)
2. "username: xxx AND hashtags: #hashtag1 #android #app" ->
{OR: [
{userName: "xxx"},
{hashtags: ["#hashtag1", "#android", "#app"]}
]
}
Node(
Node(null, "username:xxx", null),
AND,
Node(
Node(
null,
"hashtags: #hashtag1",
null
),
OR, ,
Node(
Node(null, "hashtags: #android", null),
OR,
Node(null, "hashtags: #app", null)
)
)
)
- Base assumption of the app is that location data permission will be given, as a lot of core features depend on location data. As such, we did not place too much consideration on the case where the user declines location permission.
List all the known errors and bugs here. If we find bugs/errors that your team do not know of, it shows that your testing is not through.
-
For UI test was done on the test module
ui
. Following UI functionalities were tested :- Logging in
- Changing the feed page
- Creating different types of posts
- Canceling posts
- Creating scheduled post
- Searching with specific hashtag
- Clicking like, block, follow button for checking like/unlike, block/unblock, follow/unfollow
-
Part of methods for UI Tests below methods which are based on uses references:
MyViewAction
- Activates an item (e.g. like button, follow button etc) of specific post in recyclerview
RecyclerViewMatcher
- Detects status of an item of specific post in recyclerview
- Returns false if no item and input id is matched
setChecked
- Sets status of an item
Data Model
Api
Utils
Not covered in unit test:
-
ui.fragments
andui.activity
submodules are covered by Espresso UI tests instead. -
All classes
data/repository
module andFirebaseAuthLiveData
- Testing repository class requires mocking
FirebaseFirestore
.
- Testing repository class requires mocking
-
MockLocation
requires to retrieve live location data- Submodules
tasks
andxmlresource
requires mocking Firebase Firestore or a repository class.
- Easy: 6
- Medium: 5
- Hard: 1
- Very Hard: 1
Improved Search
- Search functionality can handle partially valid and invalid search queries. (medium)
UI Design and Testing
- UI tests using espresso or similar. Please note that your tests must be of reasonable quality. ( For UI testing, you may use something such as espresso) (hard)
Greater Data Usage, Handling and Sophistication
- Read data instances from multiple local files in different formats (JSON, XML or Bespoken). ( easy)
- User profile activity containing a media file (image, animation (e.g. gif), video). (easy)
- Use GPS information. (easy)
User Interactivity
- The ability to micro-interact with 'posts' (e.g. like, report, etc.) [stored in-memory]. (easy)
- The ability for users to ‘follow’ other users. There must be an adjustment to either the user’s timeline in relation to their following users or a section specifically dedicated to posts by followed users. [stored in-memory] (medium)
- Scheduled actions. At least two different types of actions must be schedulable. For example, a user can schedule a post, a like, a follow, a comment, etc. (medium)
User Privacy
- Privacy II: A user can only see a profile that is Public (consider that there are at least two types of profiles: public and private). (easy)
Peer-to-Peer Messaging
- Privacy I: provide users with the ability to ‘block’ users. Preventing them from directly messaging them. (medium)
Firebase Integration
- Use Firebase to implement user Authentication/Authorisation. (easy)
- Use Firebase to persist all data used in your app (this item replace the requirement to retrieve data from a local file) (medium)
- Using Firebase or another remote database to store user posts and having a user’s timeline update as the remote database is updated without restarting the application. E.g. User A makes a post, user B on a separate instance of the application sees user A’s post appear on their timeline without restarting their application. (very hard)