Skip to content

Latest commit

 

History

History
364 lines (282 loc) · 9.58 KB

File metadata and controls

364 lines (282 loc) · 9.58 KB

Firebase + TinyDB Integration Guide for GreenTime App

Overview

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 parentId and every user gets a personalId for eco points tracking

System Architecture

ID System

Parent ID

  • 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

Personal ID

  • 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_map and Firestore under ecoPointsData collection
  • Contains:
    • ecoPoints: Integer counter for eco points
    • waterSaved: Double value for liters of water saved
    • co2Saved: Double value for kg of CO2 saved
    • achievements: List of achievement IDs unlocked
    • lastUpdated: Timestamp of last update

Authentication Flow

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)

Services

1. FirebaseService (services/firebase_service.dart)

Handles Firebase integration with graceful degradation to TinyDB.

Key Methods:

  • initialize(): Initialize Firebase (called in main.dart)
  • createUserWithEmailPassword(): Create new user with credentials
  • signInWithEmailPassword(): Authenticate existing user
  • signOut(): Sign out current user
  • updateEcoPoints(): Update eco point metrics in Firestore
  • storeAchievement(): Store achievement in Firestore
  • linkChildToParent(): Create parent-child relationship
  • syncOfflineData(): Sync local changes to Firestore when connection restored

2. IDGeneratorService (services/id_generator_service.dart)

Manages generation and retrieval of Parent IDs and Personal IDs.

Key Methods:

  • generateParentId(): Create new parent ID
  • generatePersonalId(): Create new personal ID
  • storeParentIdMapping(): Link email to parent ID
  • getParentIdByEmail(): Retrieve parent ID
  • storePersonalIdMapping(): Create personal ID entry with initial eco data
  • getPersonalIdByEmail(): Retrieve personal ID
  • getPersonalIdData(): Get all eco point data for personal ID
  • updatePersonalIdEcoData(): Update eco metrics

3. AuthService (services/auth_service.dart)

Enhanced authentication service with Firebase + TinyDB hybrid support.

Key Methods:

  • signUp(): Register new user (Firebase primary, TinyDB fallback)
  • signIn(): Authenticate user
  • signOut(): Clear session data
  • isSignedIn(): Check authentication status
  • getCurrentUserId(): Get current user's ID
  • getCurrentUserEmail(): Get current user's email
  • getCurrentUserPersonalId(): Get personal ID for current user
  • getCurrentUserParentId(): Get parent ID if user is parent
  • linkChildToParent(): Link child account to parent
  • getUserData(): Retrieve full user profile

4. AppState (Models/app_state.dart)

Enhanced state management with Personal ID and Parent ID tracking.

New Properties:

  • personalId: UUID for eco points tracking
  • parentId: UUID for parent accounts
  • achievements: List of unlocked achievements

Enhanced Methods:

  • addAchievement(): Add achievement and sync to personal ID
  • setEcoPoints(), addEcoPoints(), deductEcoPoints(): Updated to sync with personal ID
  • setEcoImpact(): Update all environmental metrics

User Data Structure

TinyDB Storage

{
  "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"
    }
  }
}

Firestore Structure

/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

Firestore Security Rules

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

Setup Instructions

1. Update pubspec.yaml (Already Done)

Dependencies added:

  • firebase_core: ^2.24.0
  • cloud_firestore: ^4.13.0
  • firebase_auth: ^4.15.0
  • uuid: ^4.0.0

2. Firebase Console Setup

  1. Go to Firebase Console
  2. Select your "green-time-app" project
  3. Enable Authentication:
    • Go to Authentication → Sign-in method
    • Enable Email/Password provider
  4. Enable Firestore:
    • Go to Firestore Database
    • Create database in production mode
    • Deploy security rules from firestore.rules
  5. Update firebase.json configuration if needed

3. Install Dependencies

flutter pub get

4. Run App

flutter run

The app will:

  1. Try to initialize Firebase
  2. If Firebase unavailable, gracefully fallback to TinyDB offline mode
  3. Automatically sync data when connection is restored

Usage Examples

Get User's Personal ID

final appState = Provider.of<AppState>(context);
print('Personal ID: ${appState.personalId}');

// Or directly from service
final personalId = await AuthService.getCurrentUserPersonalId();

Get Parent's Parent ID

final parentId = await AuthService.getCurrentUserParentId();
print('Parent ID: $parentId');

Add Eco Points

final appState = Provider.of<AppState>(context, listen: false);
await appState.addEcoPoints(50);

// Personal ID data is automatically updated

Store Achievement

await 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');

Link Child to Parent

await AuthService.linkChildToParent(
  parentEmail: 'parent@email.com',
  childUsername: 'ecowarrior123'
);

// Firebase and TinyDB both updated

Offline Functionality

The 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);

Testing

Test files are located in test/ directory:

  • unit_tests.dart: Unit tests for services
  • integration_test.dart: Integration tests
  • test_tinydb.dart: TinyDB functionality tests

Run tests:

flutter test

Migration Notes

Existing Users

If migrating from previous version:

  1. Old user data will be automatically migrated
  2. Personal IDs will be generated on next login
  3. Historical eco points are preserved
  4. No data loss occurs

Backward Compatibility

The system maintains backward compatibility:

  • Works without Firebase (TinyDB only)
  • Gracefully degrades when Firebase unavailable
  • No breaking changes to existing screens/logic

Troubleshooting

Firebase not initializing

Check:

  1. firebase_options.dart has correct credentials
  2. Google Services JSON is in android/app/
  3. Internet connection available
  4. Firebase project is accessible

The app will automatically fallback to TinyDB if Firebase fails.

Personal ID not syncing

  • Ensure email is correctly stored in TinyDB
  • Check Firestore rules allow the operation
  • Verify Firebase credentials are valid

Data not persisting offline

  • Check TinyDB permissions
  • Verify shared_preferences is writable
  • Clear app data and retry

Future Enhancements

  1. Cloud Sync: Automatic background sync
  2. Real-time Sync: Firestore real-time listeners
  3. Encryption: Encrypt sensitive data in TinyDB
  4. Backup: Automatic backup to Firebase Storage
  5. Multi-device Sync: Sync data across devices

Support

For issues or questions:

  1. Check Firebase Console for errors
  2. Review app logs: flutter logs
  3. Verify Firestore security rules
  4. Test with Firebase Emulator Suite