import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/firebase/firebase_providers.dart'; import 'auth_repository.dart'; /// users/{uid}-Dokument des angemeldeten Nutzers, live (null = ausgeloggt). /// /// Existiert das Dokument nicht (erster Login), stößt /// [householdBootstrapProvider] den Haushalts-Bootstrap an. final userProfileProvider = StreamProvider>?>((ref) { final user = ref.watch(authStateProvider).value; if (user == null) return Stream.value(null); return ref .watch(firestoreProvider) .collection('users') .doc(user.uid) .snapshots(); }); /// Reaktiver Haushalts-Bootstrap: legt Profil + eigenen Haushalt an, sobald /// ein Nutzer angemeldet ist, für den noch kein users-Dokument existiert. /// /// Deckt alle Login-Wege ab (E-Mail-Registrierung, Apple, künftig Google) — /// unabhängig davon, wann der Router weiterleitet. Das BootstrapGate hält /// die App zurück, bis das Profil da ist, und zeigt Fehler samt /// „Erneut versuchen“ an. class HouseholdBootstrap extends Notifier> { @override AsyncValue build() { final user = ref.watch(authStateProvider).value; final profile = ref.watch(userProfileProvider).value; // Nur aktiv, wenn der Snapshot sicher zum aktuellen Nutzer gehört und // der Haushalt fehlt — bei Kontowechsel hält .value kurz den alten Stand. // Maßstab ist householdId, nicht die Dokument-Existenz: die Push- // Registrierung legt das users-Dokument auch ohne Haushalt an. if (user == null || profile == null || profile.id != user.uid || profile.data()?['householdId'] != null) { return const AsyncValue.data(null); } _run(user); return const AsyncValue.loading(); } Future _run(User user) async { try { await ref .read(authRepositoryProvider) .ensureHouseholdBootstrap(user.uid, user.email); // Kein Erfolgs-State nötig: das neue users-Dokument kommt über den // Snapshot-Stream herein und baut diesen Notifier als „fertig“ neu. } catch (error, stackTrace) { if (!ref.mounted) return; state = AsyncValue.error(error, stackTrace); } } /// Nach einem Fehler erneut versuchen (Knopf im BootstrapGate). void retry() { final user = ref.read(authStateProvider).value; if (user == null) return; state = const AsyncValue.loading(); _run(user); } } final householdBootstrapProvider = NotifierProvider>( HouseholdBootstrap.new);