Skip to content

jesuisstan/deezeroom

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

432 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

DeezerRoom

A complete mobile solution focused on music and collaborative user experience. Built with React Native, Expo, Firebase, and a separate Next.js GraphQL API server.

Live API Server: https://deezeroom-server.vercel.app/
Server Repository: https://github.com/jesuisstan/deezeroom-server

Get started with EAS Hosting.

Project Scripts

package.json includes several useful scripts for development, verification, cleaning, and building:

πŸ›  Development

npm run start β†’ Start Expo development server (default).

npm run start:clear β†’ Start Expo server with cache cleared.

npm run start:tunnel β†’ Start server using a tunnel (for external devices). Before running, ensure that ngrok is installed.

npm i -g @expo/ngrok

npm run start:tunnel:clear β†’ Start tunnel with cache cleared.

npm run android β†’ Launch app on an Android device/emulator.

npm run ios β†’ Launch app on an iOS simulator/device.

npm run web β†’ Launch app in a web browser.

βœ… Quality & Verification

npm run lint β†’ Run ESLint to check code style and potential issues.

npm run lint:fix β†’ Run ESLint with automatic fixes for code style issues.

npm run verify:deps β†’ Verify that installed dependencies match Expo SDK requirements.

npm run verify:lockfile β†’ Dry-run installation to ensure package-lock.json is valid and consistent.

🧹 Cleaning & Reinstall

npm run clean β†’ Remove all generated folders (node_modules, lockfile, Expo, Android/iOS/web builds).

npm run fresh β†’ Clean the project and reinstall dependencies from scratch.

πŸ“¦ Building

npm run build:dev:android β†’ Create a development build for Android in the cloud.

npm run build:dev:ios β†’ Create a development build for iOS in the cloud.

npm run build:dev:web β†’ Create a development build for Web in the cloud.

npm run build:prod:android β†’ Create a production build for Android in the cloud.

Usefull commands

Ensure installation

"preinstall" / "prepare":

npm install -g eas-cli && npm install --global @expo/ngrok@^4.1.0

Managing Environment Variables

Check cloud envirement:

eas env:list

Push secret file (like google-services.json) to cloud builder:

npx eas env:create --scope project --name GOOGLE_SERVICES_JSON --type file --value ./credentials/android/google-services.json
npx eas env:create --scope project --name FIREBASE_ADMINSDK_JSON --type file --value ./credentials/android/deezeroom-1bc3c-firebase-adminsdk-fbsvc-e2b4ace5e3.json

πŸ— Application Architecture

Backend Architecture

DeezerRoom uses a hybrid backend architecture combining:

  • GraphQL API Server (Next.js) - Separate server for music data operations

  • Firebase - Real-time collaborative features

    • Firestore for real-time database (events, playlists, user profiles)
    • Firebase Authentication (email/password, Google OAuth)
    • Firebase Storage (avatars, cover images)
    • Cloud Messaging for push notifications

Environment Variables:

  • EXPO_PUBLIC_SERVER_URL - URL of the GraphQL API server (defaults to http://localhost:3000 in dev, https://deezeroom-server.vercel.app in production)
  • EXPO_PUBLIC_APP_URL - URL of the Expo app itself (for deep linking)

Development Setup:

For local development, you need to run both the client and server:

  1. Start the GraphQL server:

    cd deezeroom-server
    npm run dev

    Server will be available at http://localhost:3000/api/graphql

  2. Start the Expo client:

    cd deezeroom
    npm run start

    The client will automatically connect to the local server in dev mode.

Navigation Flow

The application uses Expo Router with Stack.Protected screens for route-based authentication:

graph TD
    A["App Start"] --> B["RootLayout.tsx"]
    B --> C["DeezeroomApp.tsx"]
    C --> D["Stack Navigator<br/>with Protected Screens"]
    D --> E["UserProvider<br/>(Auth State)"]

    E --> F{"User State Check"}

    F -->|"Not Authenticated"| G["Stack.Protected guard={!isAuthenticated}"]
    F -->|"Authenticated + Email Verified"| H["Stack.Protected guard={isAuthenticated && isEmailVerified}"]
    F -->|"Authenticated + Email NOT Verified"| I["Stack.Protected guard={isAuthenticated && !isEmailVerified}"]

    G --> G1["auth/index.tsx<br/>(WelcomeScreen)"]
    G1 --> G2["Continue with Email"]
    G2 --> G3["auth/login.tsx<br/>(LoginScreen)"]
    G3 --> G4["Link: Create account"]
    G4 --> G5["auth/register.tsx<br/>(RegisterScreen)"]
    G3 --> G6["Link: Forgot password"]
    G6 --> G7["auth/reset-password.tsx<br/>(ResetPasswordScreen)"]
    G3 --> G8["Back Button"]
    G5 --> G8
    G7 --> G8

    G1 --> G9["Google Sign In"]
    G9 --> G10["Firebase Auth"]
    G10 --> E

    H --> H1["(tabs)/_layout.tsx<br/>(Tabs Navigator)"]
    H1 --> H2["(tabs)/index.tsx<br/>(Home Tab)"]
    H1 --> H3["(tabs)/events/index.tsx<br/>(Events Tab)"]
    H1 --> H4["(tabs)/playlists/index.tsx<br/>(Playlists Tab)"]
    H1 --> H5["(tabs)/profile/index.tsx<br/>(Profile Tab)"]

    H5 --> H6["(tabs)/profile/_layout.tsx<br/>(Stack Navigator)"]
    H6 --> H7["profile/index.tsx<br/>(Profile Screen)"]
    H6 --> H8["profile/settings.tsx<br/>(Settings Screen)"]
    H6 --> H9["profile/edit-profile.tsx<br/>(Edit Profile Screen)"]

    H7 --> H10["Sign Out Button"]
    H10 --> H11["UserProvider.signOut()"]
    H11 --> E

    H --> H12["notifications/index.tsx<br/>(Notifications Screen)"]
    H --> H13["player.tsx<br/>(Player Modal)"]
    H --> H14["users/[id]/index.tsx<br/>(Other User Profile)"]

    H --> H15["about/index.tsx<br/>(About Screen - Available to all)"]

    I --> I1["verify-email.tsx<br/>(EmailVerificationScreen)"]
    I1 --> I2["Resend verification"]
    I2 --> I3["Firebase sendEmailVerification"]
    I1 --> I4["I have verified"]
    I4 --> I5["Firebase reload + check"]
    I5 --> E
    I1 --> I6["Back Button"]
    I6 --> I7["Sign out + redirect to auth"]
    I7 --> E

    style D fill:#ffeaa7
    style G1 fill:#fff3e0
    style G3 fill:#fff3e0
    style G5 fill:#fff3e0
    style G7 fill:#fff3e0
    style H1 fill:#e8f5e8
    style H6 fill:#e8f5e8
    style H7 fill:#e8f5e8
    style I1 fill:#e1f5fe
    style E fill:#fab1a0
Loading

Key Components

  • DeezeroomApp: Main navigation component with Stack.Protected screens
  • UserProvider: Manages Firebase authentication state and user profile data
  • Stack Navigator: Handles all screen transitions with route-based protection
  • WelcomeScreen: Entry screen with Google Sign-In and "Continue with email"
  • LoginScreen: Email/password login form (/auth/login)
  • RegisterScreen: Email/password registration form (/auth/register)
  • ResetPasswordScreen: Password reset form (/auth/reset-password)
  • VerifyEmailScreen: Email verification screen (/verify-email)

Authentication States & Protected Routes

  1. Loading: Shows ActivityIndicatorScreen while checking auth state
  2. Unauthenticated: Protected by guard={!isAuthenticated}
    • /auth/* - All authentication screens
  3. Authenticated + Email Verified: Protected by guard={isAuthenticated && isEmailVerified}
    • /(tabs)/* - Main app with tab navigation (includes profile tab with nested stack)
    • /notifications - Notifications screen
    • /player - Player modal
    • /users/[id] - Other user profiles
    • /about - About screen (available to all authenticated users)
  4. Authenticated + Email NOT Verified: Protected by guard={isAuthenticated && !isEmailVerified}
    • /verify-email - Email verification screen

Navigation Rules

  • Stack.Protected automatically handles route access based on authentication state
  • No manual redirects - routes are protected at the component level
  • Email verification required - users must verify email before accessing main app
  • Type-safe routing - All navigation through Expo Router with TypeScript support
  • Fallback handling - +not-found screen for invalid routes

Backend Services

  • GraphQL API (Next.js Server):

    • searchTracks - Search tracks by keyword
    • getPopularTracks - Get trending tracks
    • track - Get track details by ID
    • searchArtists - Search artists by name
    • artistsByIds - Batch fetch artists by IDs
  • Firebase Services:

    • UserService (firebase-service-user.ts) - Authentication and profile management
    • EventService (firebase-service-events.ts) - Music Track Vote events with real-time voting
    • PlaylistService (firebase-service-playlists.ts) - Collaborative real-time playlist editing
    • Connections (firebase-service-connections.ts) - Friend relationships and social features (functions, not a class)
    • NotificationService (firebase-service-notifications.ts) - Push notifications via Expo (singleton instance)
    • StorageService (firebase-service-storage.ts) - File storage and management

Important links

  • Android DEV build apk: version 2.54.1, 26/11/2025. Download the .apk file
  • Android PRODUCTION build apk: version 2.54.2, 27/11/2025. Download the .apk file
  • DeezeRoom WEB App: Github codebase. Deployed on Expo, available here
  • DeezeRoom graphQL API (server): Github codebase. Deployed on Vercel, available here
  • Firebase console: available here
  • EXPO dev project: Expo development console is available here

Releases

No releases published

Packages

 
 
 

Contributors

Languages