fluttergoogle-cloud-firestoreprovider

Widget is not refreshed when provider value changes


I have a users Firestore collection where the ids are my users uid. When a user logs in (with Firebase auth), i'd like to wrap the whole application by the corresponding firestore document.

My code is the following:

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        StreamProvider(
          create: (context) => FirebaseFirestore.instance
              .collection('users')
              .doc(FirebaseAuth.instance.currentUser?.uid)
              .snapshots(),
          initialData: null,
        )
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
          useMaterial3: true,
        ),
        home: const AuthentificationWapper(),
      ),
    );
  }
}

class AuthentificationWapper extends StatefulWidget {
  const AuthentificationWapper({super.key});

  @override
  State<AuthentificationWapper> createState() => _AuthentificationWapperState();
}

class _AuthentificationWapperState extends State<AuthentificationWapper> {
  @override
  Widget build(BuildContext context) {
    var userList =
        Provider.of<DocumentSnapshot<Map<String, dynamic>>?>(context);

    var isLogged = userList?.data() != null;

    return Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          title: Text('test'),
        ),
        body: Center(
          child: isLogged ? Text('YOU ARE LOGGED') : LogginAccount(),
        ));
  }
}

The problem is when the user logs in, AuthentificationWapper is not being updated (the log in form is still being displayed). I need to make a hot reload in order to see the text YOU ARE LOGGED


Solution

  • Multiprovider widget did the trick

    return MultiProvider(
          providers: [
            Provider<AuthentificationService>(
              create: (_) => AuthentificationService(FirebaseAuth.instance),
            ),
            StreamProvider<User?>(
              create: (context) =>
                  context.read<AuthentificationService>().authStateChanges,
              initialData: null,
            ),
            StreamProvider<DocumentSnapshot?>(
              create: (context) {
                final authService = context.read<AuthentificationService>();
                return authService.authStateChanges.asyncMap((user) {
                  if (user != null) {
                    print('Creating Firestore stream for user: ${user.uid}');
                    return FirebaseFirestore.instance
                        .collection('users')
                        .doc(user.uid)
                        .get();
                  }
                  print('No user logged in, returning null');
                  return null;
                });
              },
              initialData: null,
            ),
          ],
          child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
              useMaterial3: true,
            ),
            home: const AuthentificationWapper(),
          ),
        );