cse403-fitquest / fitquest

💪 FitQuest is a gamified fitness app that transforms users' fitness journeys into engaging RPG-style adventures.
0 stars 2 forks source link

💪 FitQuest

Gamified fitness app that transforms users' fitness progress into engaging RPG-style adventures!

[Team Resources](./team-resources.md)   |    [User Documentation](./documentation/userDoc.md)   |    [Developer Documentation](./documentation/devDoc.md)

Features   |    Setup   |    Technologies   |    Roadmap   |    Images   |    Contributors

✨ Features

📋 Setup

Before you start, you will need to have the following tools installed on your PC/Laptop: Git, Node.js (20.x LTS). In addition, it is good to have an editor to work with the code such as VSCode.

Project installation

  1. Clone the repository:

    git clone https://github.com/cse403-fitquest/fitquest
    cd fitquest
  2. Install dependencies

    npm install
  3. Run the app

    npm start

    This should display the following:

    alt text

    a. If the QR is not displayed, it is likely that you did not do the previous steps correctly. Ensure your node version is 20.x LTS, delete the package-lock.json file and /node_modules folder generated in step 2, then do another npm install and npm start.

  4. Setup device for development. Run on physical Android device using expo QR code or run on Android Emulator:

    With an android device, the fastest way to use the app is to use your physical device through expo. Download and install Exp Go SDK 51 (https://expo.dev/go?sdkVersion=51&platform=android&device=true). When the app is running after completing step 2, scan the QR code given in the terminal in the Expo Go application.

    Our app currently does not support iPhones, so using Expo Go with your iPhone will likely result in a crash or unintended bug(s).

    With other devices such as a laptop, you will need to work with an android emulator to run the app. Following the instructions from the link will take around 15 minutes to setup depending on whether you have installed android studio: https://docs.expo.dev/get-started/set-up-your-environment/?platform=android&device=simulated&mode=expo-go. Be sure to select "Android Emulator" for the first option and "Expo Go" for the second option.

Firebase Setup (OPTIONAL)

Skip this setup if you want to use data provided by us. You only need to do this setup if you wish to use your own set of data that the app can interface with.

  1. Access firebase console (https://console.firebase.google.com/)

  2. Create a new project

  3. Within the project, register a new web app

  4. Copy the configuration parameters provided by firebase and set it in firebaseConfig.ts. Example below

    const firebaseConfig = {
      apiKey: "yourAPIKey",
      authDomain: "fitquest-xxxxx.firebaseapp.com",
      projectId: "fitquest-xxxxx",
      storageBucket: "fitquest-xxxxx.appspot.com",
      messagingSenderId: "XXXXXXXXXXXX",
      appId: "X:XXXXXXXXXXXX:web:XXXXXXXXXXXXXXXXXXXXXX",
      measurementId: "X-XXXXXXXXXX"
    };
  5. You will need to add two new products in your firebase project, Authentication and Firestore. Let's configure both of them:

    a. For the Authentication product, simply choose Authentication from the list of products (should also be the first option in recommended products).

    b. Click Get Started

    c. When prompted for a sign in method, simply click "Email/Password".

    d. Enable Email/Password, and ensure that Email Link (passwordless sign-in) is disabled. You should be set for authentication now.

    e. For Firestore, simply browse the list of products and click on "Cloud Firestore".

    f. Once initialized, click on the "Create database" button.

    g. You will now be asked a series of questions to setup the database.

    h. For setting location, pick the location closest to you.

    i. For rules, pick test mode.

    j. Wait a couple seconds for the database to initialize

    k. After the database has been created, head over to the "Rules" tab and past the following ruleset:

     rules_version = '2';
     service cloud.firestore {
    
        match /databases/{database}/documents {
    
           // Shop Item collection where each document corresponds to an item
           match /items/{itemId} {
    
              // Only allow read for authenticated users
              allow read: if request.auth != null;
    
              allow create: if request.auth != null;
    
              allow update: if request.auth != null;
    
              allow delete: if request.auth != null;
           }
    
           // Friends collection where each document corresponds to a user
           match /friends/{userId} {
    
              // Only authenticated users can read their own friends document
              allow read: if request.auth != null;
    
              // Only authenticated users can create their own initial friends document
              allow create: if request.auth != null && request.auth.uid == userId;
    
              // Allow updates only if the user is authenticated and is modifying their own document
              allow update: if request.auth != null && (
    
                 // Only allow updates for specified fields: 'pendingFriendRequests', 'sentFriendRequests', 'friends'
                 request.resource.data.keys().hasAny(['pendingRequests', 'sentRequests', 'friends']) && 
    
                 // Ensure the update does not remove any other fields
                 request.resource.data.size() == resource.data.size() || 
    
                 // Or, the update must be limited to the allowed fields only
                 request.resource.data.keys().hasOnly(['pendingRequests', 'sentRequests', 'friends'])
              );
           }
    
           // Users collection where each document corresponds to a user's profile
           match /users/{userId} {
    
              // Allow read access to user data for authenticated users
              allow read: if request.auth != null;
    
              // Allow create access to user data for authenticated users for initial user data
              allow create: if request.auth != null && request.resource.data.id == request.auth.uid;
    
              // Allow the user to update their consumables or equipment
              allow update: if request.auth != null 
              // && request.auth.uid == userId && (
              //   request.resource.data.keys().hasAny(['equippedItems', 'items'])
              // );
    
              // Prevent overwriting the entire user document
              // allow update: if request.resource.data.size() == resource.data.size();
           }
    
           match /quests/{quest} {
              allow read, write:  if request.auth != null;
           }
        }
     }

    l. Your firebase project should now be set up properly. Move on to creating collections and documents inside the database.

  6. You will need to create a "quests", "items", "users", and "friends" collection in firestore.

    a. For the quests collection, you will need to fill in dummy data in the form:

      // An map with key-value pairs like below. '1' is the id of the quest.
      '1': {
         name:'Hunt Red Minotaur',
         questDescription: '',
         milestones: [
            50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000
         ],
         bossThreshold: 500,
         duration: 7 * 24 * 60 * 60 * 1000,
         normalMonsters: [
            {
            name: 'Green Slime',
            maxHealth: 80,
            health: 80,
            power: 8,
            spriteId: 'slime_green',
            },
            {
            name: 'Blue Slime',
            maxHealth: 85,
            health: 85,
            power: 9,
            spriteId: 'slime_blue',
            },
            {
            name: 'Red Slime',
            maxHealth: 75,
            health: 75,
            power: 7,
            spriteId: 'slime_red',
            },
         ],
         boss: {
            name: 'Red Minotaur',
            maxHealth: 200,
            health: 200,
            power: 15,
            speed: 15,
            spriteId: AnimatedSpriteID.MINOTAUR_RED,
         },
         createdAt: '',
         expiredAt: '',
      },

    b. For items collection, you will need to fill in data for items for users to purchase in the form:

      {
         id: "t1_dagger",
         name: "T1 Dagger",
         type: "WEAPON"
         description: "Small but mighty! Perfect for poking holes in your enemies' plans."
         spriteID: "t1_dagger"
         power: 5,
         speed: 10,
         health: 0,
         cost: 50,
         createdAt: November 9, 2024 at 6:37:29 PM UTC-8
      }

    c. Users collection can be left empty, as new documents will be created as new users registers an account.

    d. Friends collection can also be left empty, as new documents and relations will be made as users add friends.

  7. Start (or restart if already running) the server

    npm start

Configure linting

  1. Install the ESLint extention on VSCode.

  2. Reload VSCode to see changes.

  3. For ease of use, make sure to turn enable format-on-save on VSCode settings.

Testing

  1. Tests for the app can be run automatically with the following command:

    npm run test

    or you can run it in watch mode which reruns the tests automatically when saving changes with the following command:

    npm run test:dev
  2. Locate app tests under the tests folder in the root directory. There are unit tests for three parts of the app: reusable frontend components, services that interface with the firebase backend, and utility functions used throughout the different modules of the app.

  3. To start creating a new test, find an existing file module (auth, user, etc) or create a new file for a non-existant module to test for.

  4. Write tests in accordance to the existing testing convention. Look into sibling files or tests within the same file module you are testing to see how you should be writing your tests.

🚀 Technologies

This app was built with the following technologies:

🛣️ Roadmap

🖼️ Images

   
       
   
       

👥 Contributors