"This project comes from my personal experience traveling the US to visit national parks. I was looking on the google play store for an app to track which national parks we have seen vs. not seen. I assumed there would be an app that could track this for us and maybe even present a map or visualization of our progress that I could share on Facebook. This app doesn’t exist at the moment (some similar sites exist like travbuddy.com, but this isn’t exactly easy to use or very powerful). So, we should create it but why limit it to national parks?
I would like to develop an app/web platform where users can create a list of places to visit or things to do. Then other users can sign up for these lists and track their progress. We could build in national parks, national monuments, even restaurants in Lewisburg. But the best feature would be users could create new lists. This would allow very diverse and interesting lists to be created everything from Civil War battlefields to national ballparks. The site would have allow searching for nearby sites (geotagged) and leaderboards with statistics about who is in each challenge along with nice visualizations and social media connections." Prof. Alan Marchiori
- Challenges were removed from the list of desired features halfway through production, as there was no satisfactory solution found that fit the feel or theme of the app.
- The ability to create, optimize, share, follow, and join trips was added in the place of challenges, and to satisfy the lists request. Allowing users to coordinate trips without the point or leaderboard system.
- The final design ended up being entirely mobile based, there is no option for a web based platform as of launch.
- Expansion beyond just parks and national parks. Any point of interest that appears in Google Maps can be put into a trip.
- User created trips are not public by default, instead a user can create private trips, trips shared only with friends, and public trips.
- Instead of representing trip completion on the map, which would involve extensive revisions to accommodate mapping directions, we elected to simply record individual locations as visited or not.
- Directions can be found using a provided re-direct from our app to Google Maps.
- Make the process of creating and keeping track of trips easier.
- Browse different types of points of interest nearby you (for inspiration during a trip).
- Collaborate on trips with friends.
- Get ideas for fun new trips you wouldn’t have known about!
This diagram shows the navigation among different screens of our app. The navigators (orange) connects pages in that level through either stack or tab navigator. The pages (blue) represents different screens of our app, which utilize reusable components (green).
This diagram shows the system level design of our app. Right now users can access our app through downloading Expo Client on their iOS/Android devices. Our front-end is written using React Native, a JavaScript framework that allows us to build cross-platform apps. Our back-end mostly relies on Firebase services, including Realtime Database (most of our data such as locations, trips, and users), Cloud Storage (user profile images), and Cloud Functions (serverless backend code). ElasticSearch is deployed on Heroku (Bonsai addon) and is used to implement full text search functionalities that Firebase is lack of. We also utilized a variety of Google APIs for maps, places search, distance calculation, and directions.
- React Native
- react-native-maps: displaying map with markers and callouts on our main screen as well as trip's map page
- react-native-vector-icons: a collection of nice looking icons used in our app
- react-navigation: supports the navigation between different screens through stack and tab navigator
- Firebase
- Authentication: user signup/login as well as third party login (Google and Facebook)
- Realtime database: JSON format database for storing locations, trips, and users data
- Cloud storage: file storage service from Google Cloud Platform to store user profile images
- Cloud functions: back-end code without server that can be triggered by database updates or http requests
- ElasticSearch and Heroku
- ElasticSearch is used because Firebase does not support full text search.
- ElasticSearch database is updated by cloud function that listens to firebase realtime database changes
- Heroku is used to host ElasticSearch as well as express (nodejs) APIs for searching requests
- Google APIs
- Places: nearby places search for user added POIs
- Distance: for calculating distance between POIs and trip optimization
- Waypoints: for directions
- Fully interactable map with visual POIs, ability to add new locations, geo-query for location and screen size based rendering, and detailed callouts for each POI redirecting to a location information page.
- Profile page with relevant information for followers, favorite locations, profile image, user handle, users public trips.
- Trip page with ability to edit, rename, reorganize locations, and optimize trips. Each trip also includes a distance calculator to allow the user to see how their edits will change the final trip length.
- Trip optimization to efficiently reorganize all locations so that the overall trip length is at a minimum.
- Intuitive searches for locations, trips, and users based off of names, and tags.
- Push notifications to alert a user for follow request and join trip request.
- Trip map, allows users to see only the pins that are relevant to their trip.
- Third party login and verification, utilizing Gmail and Facebook to sign up for Xplor.
Users can create a new account for our app, or login through their Google or Facebook accounts.
Users can add locations that exist in the Google Places API, filter results by category, and add it to our database.
Users can create trips through trips screen or a location’s detail page, add tags and permissions, and add locations through search or from the map page.
Users can search for locations (full-text), users (by handle), and trips (by tag) using the search bar accessible from everywhere.
Users can request to join a trip by permission of the trip creator, or simply follow a trip.
- Cross platform style differences
- Layout changes between Android and iOS
- Use and interaction differences
- Trip optimization
- Utilizing Google Waypoints and Distance API
- Making the app more social
- Allowing users to follow and join trips
- Push notifications for user interaction
- Editing, creating, and making new trips and POIs
- Giving the user control over their trips and our POIs
- Documenting and refactoring the app
- Documenting every file, folder, and DB layout for future developers
- Making sure all code was easily understandable
- Building on previously learned React Native knowledge
- Seeing our application working smoothly
- Utilizing new libraries and APIs(but not too frequently)
- Learning new coding practices (asynchronous functions)
- Learning a new development flow
- Time management for a large scale project
- Better time management
- More testing of the application
- Documenting early and along the way
- Pair Programming
- Integration with Social Media
- Fixing a few bugs
- Deploying our app to Google Play and Apple Store
- Exporting our database to Mongo
Thank you Professor Alan Marchiori for being both our client and advisor during this senior design project.
- Initial requirements
- NPM - Node Package Manager
- Expo XDE - Installed on your workstation
- Expo (Expo Project) - Installed on your mobile device
- On first download open NPM and run “npm install”
This will install all requirements listed xplor package.json
- All packages must be successfully installed, as reported by NPM, for the app to successfully run
- In the Expo XDE, select “Open existing project…”
- Select the xplor project folder
- The project should automatically load in Expo, wait for the “Project opened!” message
- Once the message has displayed locate the three buttons in the upper right corner. (Publish, Share, Device)
- Publish - Pushes the app to the Expo app for testing. Note, no console commands will be printed using this method.
- Share - Presents the user with a QR code and link that you can use in the Expo app to navigate to a testing environment. The console will print out all issues using this method.
- Device will push the app to a connected device. The console will also work with this method.
File | Description |
---|---|
xplor/LoginScreens | |
button.js | Contains the button class and style sheet used in this section |
logo.js | Contains the logo class and style sheet |
xplor/LoginScreens/Login | |
ForgotPwd.js | Contains function to send a password reset email, leading to the reset password page |
ResetPwd.js | Contains the page and functionality for the user to reset their password |
loginForm.js | Contains the default login page layout and function, including redirects to other pages |
loginLogo.js | Contains the login logo and relevant style sheet |
loginOther.js | Contains the redirect for Facebook and Gmail sign in |
xplor/LoginScreens/Signup | |
signupConfirm.js | Contains the page to redirect users to their email for sign up confirmation |
signupDone.js | Contains the sign up completion page |
signupEmail.js | Contains functions to check email validity and uniqueness |
signupHandle.je | Contains functions to check handles validity and uniqueness |
signupName.js | Contains the page to input your name |
signupPwd.js | Contains the page to input your password as well as password strength verification |
xplor/components | |
CategoryFilter.js | Component to allow a user to select filters that limit the types of POIs shown on the map |
ContentGrid.js | Component to format a grid, used in displaying user's favorited locations |
CustomPinSearch.js | Component to allow users to add their own POIs to the Firebase database, and functions to verify that the POIs exist in Google Places API to ensure validity |
MapMarkerCallout.js | Component to display a preview of the POI's information and image upon pin selection |
NewTagModal.js | Component for users to add new tags to a trip |
SavedLocations.js | Component utilizing the content grid for saved locations |
SearchFilterContainer.js | Component to house search filtered search results |
SearchFilterOption.js | A component representing a possible category filter and how many locations under this category exist in a query |
SearchPlaces.js | Component to handle searching |
SearchTags.js | Component to handle the tag search feature |
SearchUsers.js | Component to handle the user search feature |
Tag.js | Component for tags |
Tags.js | Functions to add and remove tags |
TagsArea.js | Component for the tags display |
TripContainer.js | Component used to house trips and associated information |
TripsList.js | Component to display a trips list |
UserTrips.js | Contains functions to load trips, add location to trips, and for rendering the prior trip components into one feature |
xplor/components/Notifications | |
FollowApproval.js | Component to display an approval for a follow user request |
FollowRequest.js | Component to display a follow user requests, and functions to approve or deny request and send approval notification |
JoinTripApproval.js | Component to display an approval for a join trip request |
JoinTripRequest.js | Component to display a join trip requests, and functions to approve or deny request and send approval notification |
push_listener.js | Used to handle notifications received while the app is open or is opened after closing |
xplor/functions | |
FirebaseTripCode.js | Contains the first iteration of functions used to construct trips in Firebase. No longer implemented |
index.js | Initialize the Firebase configuration. |
location_to_geo.js | Contains functions to grab points from the Firebase database and convert them into geofire points |
nps_poi.js | Contains the functions to grab information from the national park service and push them to Firebase |
push_code.js | Contains the function to implement registration for push notifications |
xplor/navigators | |
LoginNav.js | Contains all constants necessary to operator the navigator leaving the login page and going to all singup options, logins, forgot/reset password, and the central page |
MainNav.js | Contains all constants necessary to operator the central navigator, including the redirects to all main pages, including map, search, profile, trips, following, create trip, location page, tag page, and settings |
MapNav.js | Contains all constants necessary for naviagtion out of the map page |
xplor/network | |
notifications.js | Contains all functions for interaction with the Firebase database for sending and deleting notifications |
pois.js | Contains all functions for interaction with the Firebase database for creating, searching, and getting details about pois |
trips.js | Contains all functions for interaction with the Firebase database for creating, editing, adding to, and managing trips; also includes the route optimization and route distance calculator |
users.js | Contains all functions for interaction with the Firebase database for user authetication, profile info editing, and getting users data |
xplor/pages | |
Contains all pages in the app | This folder contains all javascript files to implement every page in the app. The names of the files are labeled to clearly indicate which page they correlate to. These pages implement all components and functions relevant to operate their individual pages, and also implement their own unique functions for navigation, and unique database calls. |
xplor/utils | |
colors.js | Contains a standardized list of all colors used in the app |
poiTypes.js | Contains a standardized stylesheet for all poi types used on the map |
xplor | |
App.js | Entry point of the app, contains all information required for Expo to build and launch the app |
Tables/Entries | Description |
---|---|
xplor/pois | |
Location codes | Contains all of the locations and their unique information. The IDs are unique location IDs pulled from Google. |
xplor/pois/Unique-IDs | |
description | A short description for each location |
id | Identical to the unique identifier at the top level for POIs |
image | A url linking to an image for the destination |
lat | The locations latitude |
long | The locations longitude |
name | The destinations name |
type | This is used for sorting all POIs into specific categories for sorting on the map. These are: National Park, National Monument, Park, Museum, Amusement Park, Aquarium, Gallery, Bar, Campground, Library, Restaurant, Theater, Stadium, Zoo, Others |
xplor/tags | |
User entered tags | Each of these entries contain the count of how many trips include this tag, and the ID for each of these trips |
xplor/trips | |
Trip codes | Contains all of the trips and their uniquely generated ID, along with all of their relevent information |
xplor/trips/Unique-IDs | |
creator | The uniquely generated user ID from the original trip creator |
followers | The unique user ID for all of the trips followers |
locations | Contains all of the location IDs, and each location contains it's index, name, and whether or not it has been visited |
name | The trips name |
numLocs | How many locations the trip has |
participants | The unique user ID for all of the trips participants |
permission | Who is allowed to see the trip: everyone, only you, and followers |
tags | All tags for this trip |
xplor/users | |
handles | Contains all of the users handles paired with their unique IDs |
xplor/users/main | |
firstname | The firstname provided at signup |
handle | The user's chosen handle |
lastname | The lastname provided at signup |
numFollowers | How many people are following this user |
numFollowing | How many people this user is following |
saved | All saved/favorited locations identified by their unique ID. Contains that locations image, and name |
xplor/users/notifications/player-IDs/unique-notification-ID | |
data | The sender's ID |
time | The time the notification was sent |
type | A descriptor for which type of notification was sent |