loadUserState method
Loads user-specific balances and basket from FirebaseFirestore.
Fetches the document at users/{uid} and populates local state.
If the document doesn't exist, creates an empty scaffold via _persist.
All category names are canonicalized via _canon.
Side effects:
- Sets
_balancesLoadedto true on completion - Calls notifyListeners to update UI
- Creates Firestore document for first-time users
Implementation
Future<void> loadUserState() async {
if (_uid == null) {
_clear();
notifyListeners();
return;
}
try {
final doc = await _db.collection('users').doc(_uid).get();
final data = doc.data();
if (data == null) {
// First-time user: start empty; caps derive on demand
_clear();
await _persist(); // create doc scaffold
} else {
// balances
final b = (data['balances'] as Map?) ?? {};
balances = b.map((k, v) {
final key = _canon(k.toString());
final allowed = (v is Map && v['allowed'] is int)
? v['allowed'] as int
: null;
final used = (v is Map && v['used'] is int) ? v['used'] as int : 0;
return MapEntry(key, {'allowed': allowed, 'used': used});
});
// basket
final raw = (data['basket'] as List?) ?? [];
basket
..clear()
..addAll(
raw.whereType<Map>().map(
(m) => {
'upc': (m['upc'] ?? '').toString(),
'name': (m['name'] ?? '').toString(),
'category': _canon((m['category'] ?? '').toString()),
'qty': (m['qty'] is int) ? m['qty'] as int : 1,
},
),
);
}
} finally {
_balancesLoaded = true;
notifyListeners();
}
}