DocuWave is a React Native mobile application built for documentary enthusiasts. The goal of the app is to give users a single place to discover new documentaries, keep track of what they've watched, and curate a personal watchlist β whether they're online or offline.
The project was built to explore a hybrid storage architecture: user data lives first in a local SQLite database (so the app works fully offline), then gets pushed to Firebase Firestore whenever a network connection is available. This means the app is always responsive and never blocks on a network call for core functionality.
The Watchlog screen stores documentary entries β title, watch status, language, and year β directly in a SQLite database on the device using react-native-sqlite-storage. The app reads and writes to this database instantly without needing any network connection, so it works completely offline.
When the device is online, the local watchlog is automatically synced to Firestore under the authenticated user's document. This means data is backed up to the cloud and can be recovered if the app is reinstalled. Network status is checked with @react-native-community/netinfo before any sync attempt.
The Explore screen fetches documentaries from The Movie Database (TMDB) API, filtering results to genre ID 99 (Documentary). Results are paginated, cached in component state across pages, and searchable by title using a local filter over the loaded dataset.
From the Explore screen, users can bookmark any documentary with a single tap. These bookmarks are stored in Redux state, making reads instantaneous and keeping the UI reactive without extra network calls. The watchlist persists for the session and is accessible from the dedicated Watchlist screen.
Users sign up and sign in with email and password via Firebase Authentication. An auth state listener at the root navigator level routes users to the correct screen (login or home) on app launch, and handles session persistence automatically.
The app uses @react-native-community/netinfo to detect connectivity changes. Cloud sync only runs when the device is connected, preventing failed network requests from surfacing as errors to the user.
- Discover β Browse documentaries from TMDB with search and per-card bookmark toggle
- Watchlist β Instantly save/remove films with a bookmark button; view them in a poster grid
- Watchlog β Add personal entries with watch status (watched / will watch), language, and year
- Offline storage β All watchlog data is stored locally in SQLite; works without internet
- Cloud backup β Watchlog syncs to Firestore automatically when online
- Authentication β Email/password sign-up and sign-in via Firebase Auth
| Layer | Library |
|---|---|
| Framework | React Native 0.72.4 |
| Navigation | React Navigation 6 (Stack + Drawer) |
| State management | Redux Toolkit |
| Local database | react-native-sqlite-storage |
| Cloud database | Firebase Firestore |
| Authentication | Firebase Auth |
| API | TMDB (The Movie Database) |
| Icons | react-native-vector-icons (Ionicons) |
src/
βββ api/
β βββ tmdb.js # TMDB fetch helpers
βββ components/
β βββ theme.js # Colour tokens
β βββ Header.js # Shared screen header
β βββ FormComponent.js # Add/edit documentary bottom sheet
β βββ CustomDrawer.js # Sidebar drawer content
β βββ CustomPicker.js # Styled picker wrapper
β βββ createTables.js # SQLite table initialisation
β βββ fetchDataFromTable.js
βββ Navigators/
β βββ LoginNavigator.js # Root stack (auth gate)
β βββ DrawerNavigator.js # Authenticated drawer
βββ Redux/
β βββ WatchListSlice.js # Watchlist add/remove actions
β βββ Store/store.js
βββ Screens/
βββ Login.js
βββ Registration.js
βββ HomeScreen.js # Personal watchlog (SQLite)
βββ ExploreMovies.js # TMDB discovery + search
βββ DocumentaryDetail.js # Film detail view
βββ WatchList.js # Saved watchlist grid
- Node.js 16+
- Yarn
- Android Studio + Android SDK
- Java 17 (JDK)
git clone <repo-url>
cd DocuWave
yarn installCreate a .env file in the project root (this file is gitignored β never commit it):
TMDB_API_KEY=your_tmdb_api_key
TMDB_BASE_URL=https://api.themoviedb.org/3
TMDB_IMAGE_BASE_URL=https://image.tmdb.org/t/pGet a free API key at themoviedb.org.
- Create a Firebase project at console.firebase.google.com
- Enable Email/Password authentication
- Enable Firestore Database
- Download
google-services.jsonand place it atandroid/app/google-services.json
# Start Metro bundler
yarn start --reset-cache
# In a separate terminal
yarn androidThe following configuration is required for a successful build with this dependency set.
android/build.gradle
compileSdkVersion = 34andtargetSdkVersion = 34kotlinVersion = "1.8.22"with KGP classpath entryfirebase-authforced to22.1.2(fixes D8 dexer crash on newer versions)- Kotlin stdlib forced to
1.8.22across all subprojects
android/gradle.properties
kotlin.jvm.target.validation.mode=IGNOREβ suppresses the Kotlin/Java JVM target mismatch betweenkotlinc(17) andjavac(11)
See
DEVELOPMENT.mdfor a full breakdown of past build issues and their fixes.
The packages below are hard-pinned. Do not upgrade them without first upgrading React Native.
| Package | Pinned version | Reason |
|---|---|---|
react-native-reanimated |
3.6.2 |
Newer versions require RN 0.78+ |
react-native-gesture-handler |
2.13.4 |
RN 0.72 compatibility |
react-native-screens |
3.27.0 |
RN 0.72 compatibility |
react-native-safe-area-context |
4.7.4 |
RN 0.72 compatibility |
Always use Yarn for this project. Do not run npm install with NODE_ENV=production β it silently skips devDependencies (including react-native-dotenv), which breaks the Metro bundler.
# Correct
yarn add <package>
yarn install
# Will break the build
NODE_ENV=production npm installMIT