最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

flutter - Widget is not refreshed when provider value changes - Stack Overflow

programmeradmin2浏览0评论

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

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

Share Improve this question asked 2 days ago woshitomwoshitom 5,1318 gold badges40 silver badges64 bronze badges 2
  • Check out Check current auth state section of the documentation on how to listen to the changes in authentication state. – Peter Koltai Commented 2 days ago
  • Currently your code uses the FirebaseAuth.instance.currentUser value at the time when MyApp is built that's why it works on hot reload. But it is not updated when the user is logged in or out. – Peter Koltai Commented 2 days ago
Add a comment  | 

2 Answers 2

Reset to default 2

As Peter commented, right now your code uses FirebaseAuth.instance.currentUser to determine the current user, which happens to be null when that code happens to run.

What you'll want to do instead is listen for the current user by listening for authStateChanges as shown in the documentation on getting the current user. The FirebaseAuth.instance.authStateChanges() in the sample code there gives you a Stream, so you can use another StreamBuilder or StreamProvider to also make the app respond to auth state changes.

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(),
      ),
    );
发布评论

评论列表(0)

  1. 暂无评论