Skip to content

Latest commit

 

History

History
451 lines (377 loc) · 13 KB

File metadata and controls

451 lines (377 loc) · 13 KB

🔍 COMPREHENSIVE DEBUG ANALYSIS & FIX PLAN

Executive Summary

Your app has 5 critical interconnected issues caused by:

  1. Improper data flow between Firebase and local TinyDB
  2. Incomplete linking validation that only works on one screen
  3. Missing real-time UI updates for linked children count
  4. Hardcoded colors breaking theme system
  5. Missing user validation in Firebase signup

ISSUE #1: Parent-Child Linking Not Working App-Wide

Problem

✗ Linking only works inside "Link My Child" page
✗ Outside that page, app acts as if accounts aren't linked
✗ Parent dashboard doesn't recognize linked children
✗ Task creation fails because linking status unknown

Root Causes

Cause A: Data stored in wrong place

// Current (WRONG):
await TinyDB.setString('linked_children', _linkedChildren.join(','));
// Problem: Stored as CSV string, not in Firestore user document

Cause B: Linking data not synced to Firestore

// Current (WRONG):
static Future<void> linkChildToParent({
  required String parentUid,
  required String childUid,
  ...
}) async {
  // Updates Firestore ONLY
  // But parent dashboard reads from TinyDB 'linked_children' (CSV string)
  // MISMATCH: Two sources of truth!
}

Cause C: Dashboard reads stale local data

// Current (WRONG) in parent_dashboard.dart:
Future<void> _loadLinkedChildren() async {
  final linkedChildrenJson = await TinyDB.getString('linked_children');
  // Only reads TinyDB (local CSV string), ignores Firestore!
  // After restart or app refresh, linking "disappears"
}

Solution

Use Firestore as single source of truthUpdate parent document's linkedChildren arrayUpdate child document's parentId fieldAdd real-time listeners to parent dashboardRemove CSV string approach

Implementation:

  1. Firestore parent document stores linkedChildren: [childUid1, childUid2, ...] (array)
  2. Firestore child document stores parentId: parentUid (string)
  3. Parent dashboard uses StreamBuilder to listen to linkedChildren changes
  4. No more reading from TinyDB CSV strings for linking status

ISSUE #2: Badge/Number on "My Children" Not Updating

Problem

✗ Badge shows 0 even though children linked
✗ Badge only updates after restart (if at all)
✗ No real-time update when linking/unlinking

Root Causes

Cause A: Badge count reads stale local data

// Current (WRONG):
int _linkedChildren = [];
// Loads ONCE in initState, never updates
// Event if linking happens, UI stays frozen

Cause B: No listeners for linking changes

// Current: No StreamBuilder or listener
// Parent must manually call setState() (which doesn't happen)

Cause C: Firestore listeners not implemented

// Missing: StreamBuilder that watches linkedChildren array
// Should show count = linkedChildren.length

Solution

Add StreamBuilder to watch linkedChildren changesUpdate badge count in real-timeAdd loading indicator while fetching

Implementation:

StreamBuilder<DocumentSnapshot>(
  stream: _firestore.collection('users').doc(parentUid).snapshots(),
  builder: (ctx, snapshot) {
    final count = (snapshot.data?.get('linkedChildren') as List?)?.length ?? 0;
    return Badge(label: Text('$count'), ...);
  },
)

ISSUE #3: Cannot Add Tasks (Relinking Prompt)

Problem

✗ Task creation asks to "link a child again"
✗ Happens even after successful linking
✗ Task never actually created in Firestore
✗ Child doesn't see tasks on dashboard

Root Causes

Cause A: Task creation checks wrong fields

// Current (WRONG) in task creation:
if (parentId.isEmpty || childId.isEmpty) {
  throw Exception('parentId and childId cannot be empty');
}
// Problem: parentId from TinyDB 'parent_id' or Firestore?
// Problem: childId from where? Not passed correctly!

Cause B: Parent ID not properly set

// Current (WRONG):
final parentId = await TinyDB.getString('parent_id');
// Issue: What if user is parent but this key doesn't exist?
// Issue: Firebase UID ≠ parent ID from our ID generator

Cause C: Child ID not extracted from linked children

// Current (WRONG):
// Task creation needs to know which child to assign to
// But this isn't validated or passed through properly

Cause D: Firestore document structure mismatch

// Current: Tasks stored in: parents/{parentId}/tasks/{taskId}
// But parentId might be using wrong ID (personal vs UID)
// Creating path mismatch = tasks never found!

Solution

Use Firebase UID as parentId consistentlyStore parent's Firebase UID in 'current_user_uid'Pass childUid explicitly to task creationValidate linking before task creationUse StreamBuilder to show child selector

Implementation:

static Future<String?> createTask({
  required String parentUid,    // Firebase UID
  required String childUid,     // Firebase UID
  required String title,
  ...
}) async {
  // Validate linking
  final childDoc = await _firestore.collection('users').doc(childUid).get();
  final linkedParentId = childDoc.get('parentId');
  if (linkedParentId != parentUid) {
    throw Exception('Child not linked to this parent');
  }
  
  // Create task
  await _firestore
      .collection('parents')
      .doc(parentUid)
      .collection('tasks')
      .add({
        'parentId': parentUid,
        'childId': childUid,
        'title': title,
        ...
      });
}

ISSUE #4: Dark/Light Mode Broken

Problem

✗ Only buttons change color
✗ Background stays same color in child UI
✗ Widgets don't respond to theme change
✗ Colors hardcoded everywhere

Root Causes

Cause A: Hardcoded colors in widgets

// Current (WRONG) - hardcoded everywhere:
Container(
  color: const Color(0xFF5ADCDE),  // Hardcoded teal
  child: Text('Task', style: TextStyle(color: const Color(0xFF212121)))
)
// Problem: These colors never change with theme!

Cause B: Missing Theme.of(context) usage

// Should be:
Container(
  color: Theme.of(context).colorScheme.primary,  // Responds to theme
  child: Text('Task', 
    style: Theme.of(context).textTheme.bodyLarge
  )
)

Cause C: ThemeProvider works but not used consistently

// ThemeProvider implemented correctly
// But child_dashboard.dart and parent_dashboard.dart:
// - Don't use Theme.of(context).colorScheme
// - Use hardcoded Color(0xFF...) values
// - Don't watch ThemeProvider changes

Cause D: Material theme not applied to all surfaces

// AppBar uses theme ✓
// Cards might use theme ✓  
// Buttons might use theme ✓
// Text colors usually hardcoded ✗
// Container backgrounds hardcoded ✗
// FloatingActionButton hardcoded ✗

Solution

Replace all hardcoded colors with Theme.of(context).colorSchemeUse Material design tokensUpdate app_theme_modern.dart with proper color schemesTest theme toggle applies everywhere

Implementation Steps:

  1. Replace Color(0xFF5ADCDE)Theme.of(context).colorScheme.primary
  2. Replace Colors.whiteTheme.of(context).colorScheme.onPrimary
  3. Replace Color(0xFF212121)Theme.of(context).colorScheme.onSurface
  4. All Containers, Cards, Buttons use colorScheme colors
  5. All Text uses textTheme from Theme.of(context)

ISSUE #5: New Accounts Not Appearing in Firebase

Problem

✗ Can log in but user not in Firebase Auth
✗ Firestore users collection empty
✗ No user document created
✗ Only works in TinyDB (local)

Root Causes

Cause A: Firebase might not be initialized

// Current in main.dart:
try {
  await FirebaseService.initialize();
} catch (e) {
  print('Firebase initialization failed, using TinyDB offline mode: $e');
}
// Problem: If Firebase fails, silently switches to TinyDB
// User created only in TinyDB, not Firebase!

Cause B: Signup flow only creates TinyDB user

// Current in AuthService.signUp():
if (FirebaseService.isInitialized) {
  final uid = await FirebaseService.createUserWithEmailPassword(...);
  if (uid != null) {
    await TinyDB.setString('current_user_uid', uid);
    return uid;
  }
}
// Fallback: createUserWithEmailPassword() fails
return await _signUpTinyDB(...);  // Creates ONLY in TinyDB!

Cause C: Firestore user doc creation incomplete

// Current in FirebaseService.createUserWithEmailPassword():
await _firestore.collection('users').doc(uid).set({
  'uid': uid,
  'email': email,
  'username': username,
  'role': role,
  ...
});
// But if any field missing or Firestore rule denies: silent fail

Cause D: Security rules too restrictive

// Current firestore.rules:
match /users/{userId} {
  allow create: if request.auth.uid != null && 
                   request.resource.data.uid == request.auth.uid;
}
// Problem: Requires all fields to be present on create
// If field missing: entire write fails!

Solution

Ensure Firebase Auth user created firstThen create Firestore user document with all required fieldsFix Firestore security rules to be permissive on createAdd proper error handling & loggingVerify user in both Auth and Firestore before returning success

Implementation:

static Future<String?> createUserWithEmailPassword({...}) async {
  try {
    // 1. Create Firebase Auth user
    final userCredential = await _auth.createUserWithEmailAndPassword(
      email: email,
      password: password,
    );
    final uid = userCredential.user?.uid;
    if (uid == null) throw Exception('Failed to create auth user');
    
    // 2. Create Firestore user document
    await _firestore.collection('users').doc(uid).set({
      'uid': uid,
      'email': email,
      'username': username,
      'role': role,
      'createdAt': FieldValue.serverTimestamp(),
      'linkedChildren': [],  // Empty array for parents
      'parentId': null,      // Null for parents
      'ecoPoints': 0,
      'waterSaved': 0.0,
      'co2Saved': 0.0,
    }, SetOptions(merge: false));
    
    // 3. Store locally
    await TinyDB.setString('current_user_uid', uid);
    
    // 4. Verify
    final doc = await _firestore.collection('users').doc(uid).get();
    if (!doc.exists) throw Exception('User document not created');
    
    return uid;
  } catch (e) {
    print('ERROR in createUserWithEmailPassword: $e');
    rethrow;  // Don't fallback to TinyDB!
  }
}

INTERCONNECTION MAP

Issue #5: No Firebase Users
    ↓
Issue #1: Linking Not Recognized App-Wide
    ↓
Issue #3: Can't Create Tasks (No valid parentId)
    ↓
Issue #2: Badge Count Not Updating (No children to count)
    
Issue #4 (Theme): Independent but visible when other issues prevent navigation

FILE CHANGES REQUIRED

File Issue(s) Changes
lib/services/firebase_service.dart #1, #3, #5 User creation, linking logic, task validation
lib/services/auth_service.dart #1, #5 Better signup flow
lib/services/task_service.dart #3 Linking validation before task creation
lib/Screens/parent_dashboard.dart #1, #2, #4 StreamBuilder for children, use Theme.of()
lib/Screens/child_dashboard.dart #4 Use Theme.of() for all colors
lib/theme/app_theme_modern.dart #4 Ensure complete color schemes
firestore.rules #5 Loosen create restrictions
lib/Screens/add_child_screen.dart #1 Call Firebase service properly

VERIFICATION CHECKLIST

After fixes, test:

Issue #1: Parent-Child Linking

  • Parent logs in
  • Parent enters child username → links child
  • Close app completely
  • Reopen app → linking still works
  • Parent can see child on dashboard
  • Parent can create task for child

Issue #2: Badge Count

  • Link first child → badge shows 1
  • Link second child → badge updates to 2 (instantly)
  • Close/reopen app → badge still shows 2
  • Unlink child → badge updates to 1

Issue #3: Task Creation

  • Parent linked with child
  • Parent creates task
  • Task appears in Firestore parents/{parentId}/tasks
  • Child sees task on dashboard
  • Child can mark complete

Issue #4: Theme System

  • Settings → Display → Select Dark Mode
  • All widgets turn dark (not just buttons)
  • Navigate between screens → stays dark
  • Close/reopen app → still dark
  • Switch to Light Mode → all widgets light

Issue #5: New Accounts in Firebase

  • Create new parent account
  • Check Firebase Auth → user exists
  • Check Firestore users collection → document exists
  • Check all fields present: uid, email, username, role, linkedChildren, etc.

PRIORITY ORDER

  1. Fix Issue #5 first (User creation) - enables Firebase for other fixes
  2. Fix Issue #1 next (Linking) - foundation for task system
  3. Fix Issue #3 then (Task creation) - validates linking works
  4. Fix Issue #2 next (Badge count) - nice to have, should work after #1
  5. Fix Issue #4 last (Theme) - cosmetic but important for UX