A modern React Native (Expo) mobile application with Node.js/Express backend for movie taste analysis and recommendation system.
- Features
- Tech Stack
- Requirements
- Installation
- Configuration
- Usage
- API Documentation
- Database Schema
- Development
- Troubleshooting
- License
- β User Authentication: Secure registration and login system
- β Movie Taste Quiz: Interactive quiz to analyze user preferences
- β Profile Management: Automatically generated movie taste profile
- β Token-Based Security: JWT-protected API calls
- β Offline Support: Session persistence with AsyncStorage
- β Expo Go Support: Quick testing and development via QR code
- β RESTful API: Modern and scalable API architecture
- β JWT Authentication: Secure token-based authentication
- β PostgreSQL Integration: Robust and reliable database
- β CORS Support: Cross-origin request configuration
- β Transaction Management: Transaction support for data integrity
- β Profile Analysis: Automatic movie taste profile calculation
- React Native 0.74.3
- Expo SDK 51
- TypeScript 5.0.4
- React Navigation 7.x
- AsyncStorage - Local storage
- Expo Constants - Environment variables
- Node.js 18+
- Express 5.1.0
- PostgreSQL - Database
- JWT (jsonwebtoken) - Token-based authentication
- bcryptjs - Password hashing
- CORS - Cross-origin support
- Node.js 18 or higher
- npm 9+ or yarn
- PostgreSQL 12+ (local or remote)
- Expo Go app (for mobile device testing)
- Git (for version control)
git clone https://github.com/emrekurum/MovieRecommendationApp.git
cd MovieRecommendationAppnpm installcd MovieRecommendationApp-Backend
npm install
cd ..Create a new database in PostgreSQL:
CREATE DATABASE movierecommendation;Apply the schema:
psql -U postgres -d movierecommendation -f MovieRecommendationApp-Backend/database/schema.sqlOr run the schema.sql file using your PostgreSQL client.
Create a .env file in the MovieRecommendationApp-Backend directory:
cd MovieRecommendationApp-Backend
cp .env.example .envEdit the .env file:
# PostgreSQL Database Settings
DB_USER=postgres
DB_PASSWORD=your_password_here
DB_HOST=localhost
DB_PORT=5432
DB_DATABASE=movierecommendation
# Server Port
PORT=3001
# JWT Secret Key (Use a strong key!)
JWT_SECRET=your-super-secret-jwt-key-change-this-in-productionJWT_SECRET in production!
By default:
- iOS Simulator:
http://localhost:3001 - Android Emulator:
http://10.0.2.2:3001
Find the local IP address of the machine running the backend server:
Windows:
ipconfigmacOS/Linux:
ifconfig
# or
ip addrThen set the environment variable when starting Expo:
EXPO_PUBLIC_API_URL=http://192.168.1.100:3001 npm startOr create a .env file (in the root directory):
EXPO_PUBLIC_API_URL=http://192.168.1.100:3001Note: Mobile device and computer must be on the same Wi-Fi network.
cd MovieRecommendationApp-Backend
npm run dev # Development mode (auto-restart with nodemon)
# or
npm start # Production modeIf the backend is running successfully, you'll see:
Backend server running at http://localhost:3001
Successfully connected to PostgreSQL database.
npm startWhen Expo CLI starts:
- A QR code will appear in the terminal
- Open the Expo Go app on your mobile device
- Scan the QR code
- The app will load and run
Alternative Methods:
npm run android- Open in Android emulatornpm run ios- Open in iOS simulator (macOS only)npm run web- Open in web browser
- Register: Create a new user account
- Login: Sign in with your created account
- Take Quiz: Complete the movie taste test
- View Profile: See your automatically generated profile
Register a new user.
Request Body:
{
"username": "john_doe",
"email": "[email protected]",
"password": "password123"
}Response (201):
{
"message": "User successfully registered!",
"user": {
"user_id": 1,
"username": "john_doe",
"email": "[email protected]",
"created_at": "2024-01-01T00:00:00.000Z"
}
}User login.
Request Body:
{
"email": "[email protected]",
"password": "password123"
}Response (200):
{
"message": "Login successful!",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"user_id": 1,
"username": "john_doe",
"email": "[email protected]"
}
}Get quiz questions. (Token optional)
Headers:
Authorization: Bearer <token> (Optional)
Response (200):
[
{
"questionId": 1,
"questionText": "What type of movies do you prefer?",
"questionOrder": 1,
"answers": [
{
"answerId": 1,
"answerText": "Action"
},
{
"answerId": 2,
"answerText": "Drama"
}
]
}
]Submit quiz answers and update user profile. (Token required)
Headers:
Authorization: Bearer <token>
Request Body:
{
"answers": [
{
"questionId": 1,
"chosenAnswerId": 1
},
{
"questionId": 2,
"chosenAnswerId": 3
}
]
}Response (200):
{
"message": "Quiz answers successfully submitted and your profile has been updated!",
"profile": {
"summary": "Your movie taste generally includes: action, thriller, adventure.",
"tags": ["action", "thriller", "adventure", "drama", "emotional"]
},
"user": {
"user_id": 1,
"username": "john_doe",
"email": "[email protected]"
}
}user_id(SERIAL PRIMARY KEY)username(VARCHAR, UNIQUE)email(VARCHAR, UNIQUE)password_hash(VARCHAR)taste_profile_summary(TEXT)taste_profile_tags(TEXT[])created_at(TIMESTAMP)
question_id(SERIAL PRIMARY KEY)question_text(TEXT)question_order(INTEGER)created_at(TIMESTAMP)
answer_id(SERIAL PRIMARY KEY)question_id(INTEGER, FOREIGN KEY)answer_text(TEXT)answer_tags(TEXT[])created_at(TIMESTAMP)
user_id(INTEGER, FOREIGN KEY)question_id(INTEGER, FOREIGN KEY)chosen_answer_id(INTEGER, FOREIGN KEY)submitted_at(TIMESTAMP)- PRIMARY KEY (user_id, question_id)
See MovieRecommendationApp-Backend/database/schema.sql for detailed schema.
MovieRecommendationApp/
βββ src/
β βββ components/ # Reusable components
β βββ config/ # Configuration files
β β βββ apiConfig.ts # API URL configuration
β βββ context/ # React Contexts
β β βββ AuthContext.tsx # Authentication context
β βββ navigation/ # Navigation configuration
β β βββ AuthNavigator.tsx
β β βββ MainAppNavigator.tsx
β βββ screens/ # Screen components
β β βββ Auth/
β β β βββ LoginScreen.tsx
β β β βββ RegisterScreen.tsx
β β βββ Main/
β β βββ HomeScreen.tsx
β β βββ QuizScreen.tsx
β βββ services/ # API services
β βββ authService.ts
β βββ quizService.ts
β βββ httpClient.ts
βββ MovieRecommendationApp-Backend/
β βββ src/
β β βββ config/
β β β βββ db.js # Database connection
β β βββ middleware/
β β β βββ authMiddleware.js # JWT verification
β β βββ routes/
β β βββ authRoutes.js
β β βββ quizRoutes.js
β βββ database/
β β βββ schema.sql # Database schema
β βββ server.js # Express server
βββ App.tsx # Main application component
βββ app.json # Expo configuration
βββ package.json
- TypeScript: All frontend code is written in TypeScript
- ESLint: ESLint is used for code quality
- Async/Await: async/await is preferred for promises
- Error Handling: All API calls are protected with try-catch
- New Screen: Create a new folder under
src/screens/ - Navigation: Add route in
src/navigation/ - API Endpoint: Create new route in backend
- Service: Add new service function in frontend
Problem: PostgreSQL connection error
Solution: Check database credentials in .env file. Ensure PostgreSQL service is running.
Problem: Port already in use
Solution: Change PORT value in .env file or terminate the process using the port.
Problem: API requests failing
Solution:
1. Ensure backend is running
2. Check EXPO_PUBLIC_API_URL environment variable
3. Mobile device and computer must be on same Wi-Fi network
4. Check firewall settings
Problem: App not opening in Expo Go
Solution:
1. Ensure Expo Go app is up to date
2. Run npm start again
3. Rescan QR code
4. Ensure Metro bundler is running
Problem: Table not found error
Solution: Run schema.sql file to create database schema.
This project is licensed under the MIT License - see the LICENSE file for details.
- Emre Kurum - Project owner and developer
- React Native and Expo community
- All open-source library developers
Note: This project is for educational and development purposes. Additional security measures should be taken for production use.