A Flutter messaging application with real-time translation, AI-powered formality adjustment, and Firebase backend integration. Built with Clean Architecture and offline-first capabilities.
- Features
- Prerequisites
- Installation
- Firebase Setup
- Running the App
- Building for Production
- Project Structure
- Development Workflow
- Cloud Functions
- Troubleshooting
- Real-time messaging with Firebase Firestore
- Offline-first architecture using Drift (SQLite) for local caching
- Group conversations with multiple participants
- Push notifications via Firebase Cloud Messaging
- Presence indicators (online/offline, last seen)
- Typing indicators in real-time
- Automatic translation using Google Translate API
- On-device language detection with ML Kit (<50ms)
- Cloud-based translation via Firebase Functions
- Toggle between original and translated messages
- Formality adjustment using GPT-4o-mini
- Three levels: Casual, Neutral, Formal
- Rate limiting and caching for cost optimization
- Clean Architecture with feature-based organization
- Offline-first with automatic sync
- Dual storage (Firestore + Drift) for optimal performance
- Riverpod for state management with code generation
- Firebase Realtime Database for ephemeral data (presence, typing)
- Firebase Firestore for persistent data (messages, users)
-
Flutter SDK (3.0.0 or higher)
# Check Flutter installation flutter doctor -
Dart SDK (3.0.0 or higher, comes with Flutter)
-
Firebase CLI
npm install -g firebase-tools firebase login
-
Platform-Specific Requirements
iOS:
- Xcode 14.0 or higher
- CocoaPods
sudo gem install cocoapods
Android:
- Android Studio
- Android SDK (API level 21 or higher)
- Java Development Kit (JDK) 11 or higher
-
Firebase Project
- Create a project at Firebase Console
- Enable Authentication (Email/Password)
- Enable Firestore Database
- Enable Realtime Database
- Enable Cloud Functions
- Enable Cloud Storage
-
API Keys (for Cloud Functions)
- Google Cloud Translation API key
- OpenAI API key (for formality adjustment)
git clone https://github.com/yourusername/message_ai.git
cd message_aiflutter pub getThis project uses code generation for Riverpod providers and Drift database tables:
dart run build_runner build --delete-conflicting-outputsNote: Run this command whenever you modify:
- Riverpod providers (files using
@riverpod) - Drift database tables (files extending
Table)
cd ios
pod install
cd ..- Go to Firebase Console
- Click "Add project"
- Follow the setup wizard
- Enable Google Analytics (optional)
Install FlutterFire CLI:
dart pub global activate flutterfire_cliConfigure your app (run from project root):
flutterfire configureThis will:
- Create Firebase apps for iOS and Android
- Download configuration files (
google-services.json,GoogleService-Info.plist) - Generate
firebase_options.dart
In the Firebase Console, enable:
Authentication:
- Go to Authentication → Sign-in method
- Enable "Email/Password"
Firestore Database:
- Go to Firestore Database → Create database
- Choose production mode
- Select a location (e.g.,
us-central1)
Realtime Database:
- Go to Realtime Database → Create database
- Choose locked mode (will be configured via rules)
- Select same location as Firestore
Cloud Storage:
- Go to Storage → Get started
- Use default security rules
Deploy Firestore rules:
firebase deploy --only firestore:rulesDeploy Realtime Database rules:
firebase deploy --only databaseNavigate to functions directory and install dependencies:
cd functions
pip install -r requirements.txt
cd ..Configure API keys using Firebase Secret Manager:
# Set Google Translate API key
firebase functions:secrets:set TRANSLATION_API_KEY_SECRET
# Set OpenAI API key
firebase functions:secrets:set OPENAI_API_KEY_SECRETDeploy functions:
firebase deploy --only functionsAvailable Functions:
translate_message- Real-time message translationadjust_formality- AI-powered formality adjustmenton_message_created- Push notification triggeron_user_profile_updated- Display name propagation
flutter devices# Run on iOS simulator
flutter run -d iPhone
# Run on Android emulator
flutter run -d emulator-5554
# Run on physical device (connected via USB)
flutter run -d <device-id>
# Run in release mode
flutter run --releaseWhile the app is running:
- Press
rin terminal for hot reload (quick UI updates) - Press
Rin terminal for hot restart (full app restart) - Press
qto quit
open -a Simulator
# Or use Flutter
flutter emulators --launch apple_ios_simulator# List available emulators
flutter emulators
# Launch specific emulator
flutter emulators --launch <emulator-id>1. Configure Xcode Project
Open ios/Runner.xcworkspace in Xcode:
open ios/Runner.xcworkspaceConfigure:
- Bundle Identifier
- Team (Apple Developer account)
- Signing certificates
2. Build IPA
# Build for App Store
flutter build ipa --release
# Output: build/ios/ipa/message_ai.ipa3. Upload to App Store
Use Xcode or Transporter app to upload the IPA to App Store Connect.
1. Configure Signing
Create android/key.properties:
storePassword=<your-store-password>
keyPassword=<your-key-password>
keyAlias=<your-key-alias>
storeFile=<path-to-keystore-file>2. Generate Keystore (first time only)
keytool -genkey -v -keystore ~/upload-keystore.jks \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias upload3. Build APK
# Build release APK
flutter build apk --release
# Output: build/app/outputs/flutter-apk/app-release.apk4. Build App Bundle (recommended for Play Store)
# Build release app bundle
flutter build appbundle --release
# Output: build/app/outputs/bundle/release/app-release.aab5. Upload to Play Store
Upload the .aab file to Google Play Console.
flutter build web --release
# Output: build/web/Deploy to Firebase Hosting:
firebase deploy --only hostinglib/
├── core/ # Shared infrastructure
│ ├── database/ # Drift database setup, DAOs
│ │ ├── app_database.dart # Main database class
│ │ └── daos/ # Data Access Objects
│ ├── error/ # Failure classes
│ ├── network/ # Connectivity checking
│ └── providers/ # Core Riverpod providers
│
├── features/ # Feature modules (Clean Architecture)
│ ├── authentication/
│ │ ├── data/ # Data sources, models, repositories
│ │ ├── domain/ # Entities, repository interfaces, use cases
│ │ └── presentation/ # Pages, widgets, providers
│ │
│ ├── messaging/
│ │ ├── data/
│ │ │ ├── datasources/ # Firestore & Drift data sources
│ │ │ ├── models/ # DTOs for serialization
│ │ │ ├── repositories/ # Repository implementations
│ │ │ └── services/ # Presence, typing, sync services
│ │ ├── domain/
│ │ │ ├── entities/ # Message, Conversation entities
│ │ │ ├── repositories/ # Repository interfaces
│ │ │ └── usecases/ # Business logic
│ │ └── presentation/
│ │ ├── pages/ # Chat screens
│ │ ├── providers/ # State management
│ │ └── widgets/ # Reusable components
│ │
│ ├── translation/ # Translation feature
│ └── formality_adjustment/ # Formality adjustment feature
│
├── config/ # App-wide configuration
│ ├── routes/ # Navigation setup
│ └── theme/ # Theming
│
└── main.dart # App entry point
functions/ # Firebase Cloud Functions (Python)
├── main.py # Function definitions
└── requirements.txt # Python dependencies
firestore.rules # Firestore security rules
database.rules.json # Realtime Database security rules
Run code generation whenever you modify:
# One-time build
dart run build_runner build --delete-conflicting-outputs
# Watch mode (auto-rebuild on changes)
dart run build_runner watch --delete-conflicting-outputs# Analyze Dart code for issues
dart analyze
# Auto-fix issues
dart fix --apply
# Format code
dart format lib/- Create feature directory under
lib/features/ - Define domain layer:
- Entities (business objects)
- Repository interfaces
- Use cases (business logic)
- Implement data layer:
- Models (DTOs)
- Data sources (Firestore, Drift)
- Repository implementations
- Build presentation layer:
- Pages (screens)
- Widgets (UI components)
- Providers (state management)
- Run code generation:
dart run build_runner build --delete-conflicting-outputs
- Test manually (this project does not use automated tests)
All providers use code generation:
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'my_providers.g.dart'; // Generated file
@riverpod
MyService myService(Ref ref) {
return MyService(ref.watch(dependencyProvider));
}After modifying providers, run build_runner.
When modifying database tables:
- Update table definitions in
lib/core/database/ - Run code generation
- Handle migrations in
app_database.dart - Test with app restart (hot reload won't work)
# Install Firebase emulator suite
firebase init emulators
# Start emulators
firebase emulators:startConfigure Flutter app to use emulators (development only):
// In main.dart
if (kDebugMode) {
FirebaseFunctions.instance.useFunctionsEmulator('localhost', 5001);
}# Deploy all functions
firebase deploy --only functions
# Deploy specific function
firebase deploy --only functions:translate_message
# View logs
firebase functions:logFunctions use Firebase Secret Manager:
# List secrets
firebase functions:secrets:access TRANSLATION_API_KEY_SECRET
# Update secret
firebase functions:secrets:set TRANSLATION_API_KEY_SECRETBuild runner errors:
# Clean generated files and rebuild
dart run build_runner clean
dart run build_runner build --delete-conflicting-outputsHot reload not working:
- Use hot restart (press
Rin terminal) - Provider structure changes require full restart
- Database schema changes require app reinstall
Firebase connection issues:
# Reconfigure Firebase
flutterfire configure
# Check Firebase initialization in main.dartiOS build errors:
# Clean iOS build
cd ios
rm -rf Pods Podfile.lock
pod install
cd ..
flutter clean
flutter pub getAndroid build errors:
# Clean Android build
cd android
./gradlew clean
cd ..
flutter clean
flutter pub getDrift database errors:
- Delete app and reinstall (clears local database)
- Check migration logic in
app_database.dart - Verify table definitions have correct syntax:
text()()
Provider errors:
# Regenerate provider files
dart run build_runner build --delete-conflicting-outputs
# Check for circular dependencies
# Verify all providers have proper @riverpod annotation- Firebase: Firebase Documentation
- Flutter: Flutter Documentation
- Riverpod: Riverpod Documentation
- Drift: Drift Documentation
Enable verbose logging:
# Run with verbose output
flutter run -v
# View device logs (iOS)
flutter logs
# View device logs (Android)
adb logcat- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Note: This project does not use automated testing. All changes should be manually tested.
[Add your license here]
- Flutter team for the amazing framework
- Firebase for backend services
- Riverpod for state management
- ML Kit for on-device language detection
- OpenAI for GPT-4o-mini API