TextMeMail is an Android messaging + video call app built with Kotlin, Jetpack Compose, Firebase, and Agora RTC.
Current version includes authentication, account management, real‑time chat, and basic one‑to‑one video calls (test mode – no tokens required yet).
- Email / password sign up & login
- Email verification flow
- Password & email change
- Preferred language (EN / ES) persisted (DataStore + Firestore)
- Real‑time 1:1 messaging using Firestore snapshot listeners
- Basic contact list (all verified users except self)
- Reactive Compose UI for new messages
- One‑to‑one video call using Agora RTC SDK (v4)
- Dynamic channel naming per user pair
- Camera / microphone permission handling
- Local + remote video renderers
- Test / development mode (App ID only, no token)
- 100% Jetpack Compose + Material 3
- Light / Dark theme aware
- Simple, clean, mobile‑first layouts
- Runtime language switching (EN / ES)
| Layer | Technology |
|---|---|
| Language | Kotlin |
| UI | Jetpack Compose, Material 3 |
| Auth | Firebase Authentication |
| Data | Cloud Firestore (NoSQL) |
| Preferences | Jetpack DataStore (Proto / Preferences) |
| Realtime Chat | Firestore snapshot listeners |
| Video | Agora RTC SDK (4.x) |
| Build | Gradle (KTS) |
app/
└── src/main/java/com/example/textmemail/
├── MainActivity.kt # Entry + navigation + listeners
├── auth/ # EmailAuthManager & related
├── ui_auth/ # Auth / verification screens
├── ui_chat/ # Chat + contacts + compose screens
├── VideoCallActivity.kt # Agora video call screen
└── ui/theme/ # Theming (colors, typography)
- Create a Firebase project
- Enable: Authentication (Email/Password) & Firestore
- Download
google-services.json→ place inapp/ - (Optional) Set Firestore rules for authenticated access only
- Create an Agora account & project (Test mode for now)
- Copy your App ID
- Set the App ID inside
VideoCallActivity.kt:
private val appId = "<YOUR_AGORA_APP_ID>"- (Later) For production switch to secured mode with token server
Android Studio (Giraffe+). Just sync & run:
./gradlew assembleDebug
The app requests CAMERA + RECORD_AUDIO at runtime for video calls.
- User registers (email, password, name, language) → Firestore
users/{uid} - Email verification required before chat access
- Contact list loads all other users (excluding current)
- Chat screen listens to message thread via Firestore collection(s)
- Video call button creates / joins an Agora channel derived from both UIDs
- Firebase Auth handles credentials + email verification
- Firestore rules should restrict reads/writes to authenticated users
- (Planned) Per‑chat access rules & message validation
- (Planned) Token server for Agora (production hardening)
| Status | Item |
|---|---|
| ✅ | Firebase Auth (register / login / verify) |
| ✅ | Profile & language preference persistence |
| ✅ | Real‑time messaging (Firestore) |
| ✅ | Basic 1:1 video call (Agora test mode) |
| 🔜 | Incoming call invitations (ring / accept / reject) |
| 🔜 | Push notifications (FCM) for new messages / calls |
| 🔜 | Call history & missed call states |
| 🔜 | Secure Agora token backend |
| 🔜 | Message delivery & read receipts |
Legend: ✅ Done · 🔜 Planned
- Introduce call invitation collection + listener
- Add FCM integration for background call / message alerts
- Migrate video call configuration to a central manager
- Replace hardcoded App ID with BuildConfig + local gradle property
Feel free to use, modify, and distribute for personal or academic projects.
Open to lightweight academic / learning contributions. PRs welcome (small, focused changes preferred).
