Reelit
Every challenge I faced while building Reelit, documented.
PostgreSQL Was Using the Wrong Hostname
My backend tried connecting to PostgreSQL using localhost, which does not work for container-to-container communication.
I changed the hostname to the Docker service name db.
Inside Docker Compose, services should communicate using service names, not localhost.
Docker Containers Could Not Find Each Other
Even after using db, I got could not translate host name "db" to address.
I found that the containers were not connected to the same Docker network and recreated them correctly.
Correct hostnames only work when containers actually share a network.
SQLAlchemy Models Used Different Base Classes
Only some database tables were being created because different models were using different Base classes.
I moved every model to one shared Base from app.database.
All related SQLAlchemy models need to share the same declarative Base.
Database Models and Actual Tables Went Out of Sync
The backend expected fields like is_creator, but those columns did not exist in PostgreSQL.
I added the missing columns and synchronized the schema.
Updating a model does not automatically update an existing database.
Ports Were Already in Use
Ports 5432, 6379, and 8000 were sometimes occupied by old services or Docker processes.
I identified and stopped the conflicting processes.
A server startup failure is not always a code problem. Sometimes the port is simply busy.
Redis Connection Kept Failing
I got errors like Error 10061 connecting to localhost:6379.
I checked whether Redis was actually running and corrected the hostname for each environment.
Connection issues can come from both a dead service and incorrect configuration.
Docker Failed Because of Permissions
On Linux, Docker commands failed with permission errors while accessing the Docker daemon.
I added the user to the Docker group and refreshed the session.
Installing Docker is not enough; the current user also needs permission to access it.
Docker Images and Cache Became Corrupted
I faced errors like No such image: sha256... and ContainerConfig.
I cleaned stale images, containers, volumes, and rebuilt everything.
Sometimes the application code is fine and the Docker environment itself is broken.
Google Sign-In Failed with ApiException: 10
Google login completely failed because the signing configuration did not match Firebase.
I generated the SHA fingerprints, added them to Firebase, and downloaded a fresh google-services.json.
Google Sign-In depends heavily on correct SHA fingerprints and OAuth configuration.
Google Login Worked but the User Was Not Saved
Firebase authentication succeeded, but no user appeared in my PostgreSQL database.
I explicitly called my backend Google login flow after Firebase authentication.
Firebase login and backend user creation are two separate steps.
Google Login Returned Backend Errors
At different points, Google login returned 404 because the endpoint was missing and 500 because my User model received an invalid is_active field.
I added the missing endpoint and aligned user creation with the actual SQLAlchemy model.
Authentication can fail even after Google succeeds because the backend contract is still wrong.
Tokens Expired or Were Missing from Requests
Uploads and protected endpoints failed with 401 Unauthorized or Invalid or expired token.
I corrected the Authorization: Bearer <token> header and improved re-authentication and token handling.
Authentication is not finished after login; every protected request needs valid token handling.
Firebase Was Not Initialized Before Use
The app crashed with No Firebase App '[DEFAULT]' has been created.
I initialized Firebase before accessing authentication services.
SDK initialization order matters.
Profile Updates Looked Successful but Did Not Save
I changed the user's name in the app, but the old name kept appearing.
I found a mismatch between the Flutter request and FastAPI endpoint and standardized the update flow around the correct JSON body.
Frontend and backend must agree exactly on payload structure.
User State Was Duplicated Across Providers
ProfileProvider and ReelitAuthProvider both stored user data, which caused stale values and synchronization bugs.
I simplified the architecture and moved toward one source of truth.
Duplicating the same state in multiple places creates hard-to-track bugs.
Categories Could Not Be Selected
Category cards looked correct but taps did not behave properly with my Selector and GestureDetector setup.
I reworked the widget structure and used Consumer where broader state updates were required.
Performance optimization is useless if interaction becomes unreliable.
Navigation State Became Inconsistent
Multiple bottom navigation icons appeared highlighted, and at one point I had duplicate navigation bars.
I corrected selected-index handling and gave navigation one clear owner.
Shared navigation should be controlled from one place.
Role Selection Was Skipped After Login
New users sometimes entered the app directly instead of seeing the creator/user role selection screen.
I updated AuthWrapper to check the stored onboarding and role state.
Being authenticated does not mean onboarding is complete.
Release APK Looked Zoomed In
The UI looked fine during development but appeared zoomed in in the release APK.
I traced the issue to Transform.scale and removed it.
Debug and release builds can behave differently, so both need real-device testing.
Android Storage Permissions Kept Breaking
Downloads failed on newer Android versions with errors like PathAccessException: Operation not permitted.
I added version-aware permission handling and dealt with newer media permissions such as READ_MEDIA_VIDEO.
Android storage is not one universal permission anymore; behavior changes across OS versions.
Reels Were Not Saving to the Expected Folder
Downloads completed, but users could not find the files where expected.
I corrected the download destination for the device setup I was testing and validated the actual file path.
Android file paths should never be assumed without testing on real devices.
Deleted Reels Still Appeared in the App
Users could delete a video from the gallery, but Reelit still showed it.
I added file-existence checks and better synchronization with external file changes.
A saved file path does not guarantee that the file still exists.
Realme Phones Exposed .trashed Files
On a Realme device, deleted videos were moved into .trashed files and Reelit treated them as normal reels.
I filtered .trashed paths and filenames.
Real devices expose OEM-specific behavior that emulators may never show.
Thumbnail Generation Was Slow and Sometimes Failed
Thumbnails were regenerated after every restart, and generation failed if the original video had already been deleted.
I added SQLite-based persistent caching and file-existence checks.
Expensive work should be cached, and local files should always be validated before processing.
Too Many Downloads Slowed Down the Phone
Starting around 50 downloads together made the app and device unstable.
I built a controlled queue with maxConcurrentDownloads = 3.
More concurrency does not automatically mean more speed.
S3 URLs Returned 403 Forbidden
The backend returned valid-looking video URLs, but downloads still failed.
I corrected S3 access configuration and used CloudFront for media delivery where appropriate.
A valid URL does not mean the user is authorized to access the file.
S3 Uploads Failed with AccessControlListNotSupported
Upload requests failed because the code tried to apply an ACL that the bucket configuration did not support.
I removed the unnecessary ACL parameter.
Modern S3 Object Ownership settings can disable ACL-based access completely.
Video Compression Failed Inside Docker
Compression worked conceptually, but the backend container could not run it because FFmpeg was missing.
I installed FFmpeg inside the Docker image and rebuilt it.
A dependency installed on my laptop does not automatically exist inside a container.
API URLs Were Built Incorrectly
Some requests became /api/api/auth/login, while others missed /api entirely.
I centralized API URL construction and followed one convention for base URLs and endpoints.
Small inconsistencies in API constants can break entire features.
EC2 Deployment Failed for Reasons Outside the App
I faced SSH failures because port 22 was missing from the security group, missing dependencies because requirements.txt was incomplete, and server-side environment issues that did not appear locally.
I corrected EC2 networking rules, restored dependencies, and rebuilt the deployment environment.
Deployment is its own engineering layer. Code that works locally can still fail because of infrastructure, permissions, networking, or missing dependencies.