The GreenTime app now integrates Firebase with TinyDB for a robust hybrid authentication and data storage system:
- Firebase: Used for cloud authentication and remote data synchronization
- TinyDB: Local fallback for offline functionality and user credentials storage
- Unique IDs System: Every parent gets a
parentIdand every user gets apersonalIdfor eco points tracking
- Type: Unique UUID generated for each parent account
- Purpose: Identifies parent accounts uniquely across the system
- Storage: Stored in TinyDB and Firestore under user profile
- Generated: Automatically when parent signs up
- Type: Unique UUID generated for each user (parent or child)
- Purpose: Stores all eco point data, achievements, and environmental impact metrics
- Storage: Stored in TinyDB under
personal_ids_mapand Firestore underecoPointsDatacollection - Contains:
ecoPoints: Integer counter for eco pointswaterSaved: Double value for liters of water savedco2Saved: Double value for kg of CO2 savedachievements: List of achievement IDs unlockedlastUpdated: Timestamp of last update
User Input (email, password)
↓
Try Firebase Auth ← Firebase available?
↓ (Success or Failure)
Fallback to TinyDB ← Offline or Firebase unavailable
↓
Store credentials in TinyDB
Store in Firestore (if Firebase available)
Handles Firebase integration with graceful degradation to TinyDB.
Key Methods:
initialize(): Initialize Firebase (called in main.dart)createUserWithEmailPassword(): Create new user with credentialssignInWithEmailPassword(): Authenticate existing usersignOut(): Sign out current userupdateEcoPoints(): Update eco point metrics in FirestorestoreAchievement(): Store achievement in FirestorelinkChildToParent(): Create parent-child relationshipsyncOfflineData(): Sync local changes to Firestore when connection restored
Manages generation and retrieval of Parent IDs and Personal IDs.
Key Methods:
generateParentId(): Create new parent IDgeneratePersonalId(): Create new personal IDstoreParentIdMapping(): Link email to parent IDgetParentIdByEmail(): Retrieve parent IDstorePersonalIdMapping(): Create personal ID entry with initial eco datagetPersonalIdByEmail(): Retrieve personal IDgetPersonalIdData(): Get all eco point data for personal IDupdatePersonalIdEcoData(): Update eco metrics
Enhanced authentication service with Firebase + TinyDB hybrid support.
Key Methods:
signUp(): Register new user (Firebase primary, TinyDB fallback)signIn(): Authenticate usersignOut(): Clear session dataisSignedIn(): Check authentication statusgetCurrentUserId(): Get current user's IDgetCurrentUserEmail(): Get current user's emailgetCurrentUserPersonalId(): Get personal ID for current usergetCurrentUserParentId(): Get parent ID if user is parentlinkChildToParent(): Link child account to parentgetUserData(): Retrieve full user profile
Enhanced state management with Personal ID and Parent ID tracking.
New Properties:
personalId: UUID for eco points trackingparentId: UUID for parent accountsachievements: List of unlocked achievements
Enhanced Methods:
addAchievement(): Add achievement and sync to personal IDsetEcoPoints(),addEcoPoints(),deductEcoPoints(): Updated to sync with personal IDsetEcoImpact(): Update all environmental metrics
{
"users": {
"user@email.com": {
"email": "user@email.com",
"password": "hashedPassword",
"username": "ecowarrior123",
"role": "parent|kid",
"uid": "firebase-uid",
"personalId": "uuid-for-eco-points",
"parentId": "uuid-for-parent-only",
"ecoPoints": 1500,
"waterSaved": 250.5,
"co2Saved": 45.2,
"createdAt": "2024-01-15T10:30:00Z"
}
},
"parent_ids_map": {
"parent@email.com": {
"parentId": "uuid",
"createdAt": "2024-01-15T10:30:00Z"
}
},
"personal_ids_map": {
"user@email.com": {
"personalId": "uuid",
"ecoPoints": 1500,
"waterSaved": 250.5,
"co2Saved": 45.2,
"achievements": ["first-task", "water-saver"],
"createdAt": "2024-01-15T10:30:00Z",
"lastUpdated": "2024-01-15T14:45:00Z"
}
}
}
/users/{uid}
- uid: Firebase UID
- email: User email
- username: Display username
- role: parent|kid
- personalId: UUID for eco points
- parentId: UUID (parents only)
- ecoPoints: Integer
- waterSaved: Double
- co2Saved: Double
- createdAt: Timestamp
- lastUpdated: Timestamp
/achievements/{achievementId}
- title: String
- description: String
- unlockedAt: Timestamp
/linkedChildren/{childUserId}
- childUid: Firebase UID
- childUsername: String
- linkedAt: Timestamp
/tasks/{taskId}
- taskData: {...}
/ecoPointsData/{personalId}
- uid: User's Firebase UID
- ecoPoints: Integer
- waterSaved: Double
- co2Saved: Double
- achievements: Array
- lastUpdated: Timestamp
Security rules are configured in firestore.rules with:
- Users can only read/write their own data
- Parents can view linked children's data
- Public read/write access is denied by default
- Authentication required for all operations
Dependencies added:
firebase_core: ^2.24.0cloud_firestore: ^4.13.0firebase_auth: ^4.15.0uuid: ^4.0.0
- Go to Firebase Console
- Select your "green-time-app" project
- Enable Authentication:
- Go to Authentication → Sign-in method
- Enable Email/Password provider
- Enable Firestore:
- Go to Firestore Database
- Create database in production mode
- Deploy security rules from
firestore.rules
- Update firebase.json configuration if needed
flutter pub getflutter runThe app will:
- Try to initialize Firebase
- If Firebase unavailable, gracefully fallback to TinyDB offline mode
- Automatically sync data when connection is restored
final appState = Provider.of<AppState>(context);
print('Personal ID: ${appState.personalId}');
// Or directly from service
final personalId = await AuthService.getCurrentUserPersonalId();final parentId = await AuthService.getCurrentUserParentId();
print('Parent ID: $parentId');final appState = Provider.of<AppState>(context, listen: false);
await appState.addEcoPoints(50);
// Personal ID data is automatically updatedawait FirebaseService.storeAchievement(
uid: currentUid,
achievementId: 'water-saver-10l',
title: 'Water Saver',
description: 'Saved 10 liters of water',
);
// Also update local personal ID
await appState.addAchievement('water-saver-10l');await AuthService.linkChildToParent(
parentEmail: 'parent@email.com',
childUsername: 'ecowarrior123'
);
// Firebase and TinyDB both updatedThe app works completely offline using TinyDB when:
- Firebase is unavailable
- Device has no internet connection
- Firebase initialization fails
Data Sync: When connection is restored:
await FirebaseService.syncOfflineData(currentUid);Test files are located in test/ directory:
unit_tests.dart: Unit tests for servicesintegration_test.dart: Integration teststest_tinydb.dart: TinyDB functionality tests
Run tests:
flutter testIf migrating from previous version:
- Old user data will be automatically migrated
- Personal IDs will be generated on next login
- Historical eco points are preserved
- No data loss occurs
The system maintains backward compatibility:
- Works without Firebase (TinyDB only)
- Gracefully degrades when Firebase unavailable
- No breaking changes to existing screens/logic
Check:
firebase_options.darthas correct credentials- Google Services JSON is in
android/app/ - Internet connection available
- Firebase project is accessible
The app will automatically fallback to TinyDB if Firebase fails.
- Ensure email is correctly stored in TinyDB
- Check Firestore rules allow the operation
- Verify Firebase credentials are valid
- Check TinyDB permissions
- Verify
shared_preferencesis writable - Clear app data and retry
- Cloud Sync: Automatic background sync
- Real-time Sync: Firestore real-time listeners
- Encryption: Encrypt sensitive data in TinyDB
- Backup: Automatic backup to Firebase Storage
- Multi-device Sync: Sync data across devices
For issues or questions:
- Check Firebase Console for errors
- Review app logs:
flutter logs - Verify Firestore security rules
- Test with Firebase Emulator Suite