StreamBuilder未更新Flutter中的Firestore数据

wlwcrazw  于 2022-11-17  发布在  Flutter
关注(0)|答案(3)|浏览(185)

我正在做一个Flutter应用程序,我试图在应用程序中获取用户的数据。
因此,基本上,用户使用他的信息(姓名、电子邮件、密码)进行注册,当他登录时,这些数据将显示在ProfilePage中。
根据Firestore文档,我应该使用StreamBuilder来获取他的数据。
在这一点上,一切都工作正常。
问题在于,当用户注销而另一个用户登录时,ProfilePage会显示前一个用户的数据(该用户已注销)。
只有当我重启应用程序,我才能得到正确的数据。
下面是我的ProfilePage

class UserInformation extends StatefulWidget {
  @override
  _UserInformationState createState() => _UserInformationState();
}

class _UserInformationState extends State<UserInformation> {

  final _uid = FirebaseAuth.instance.currentUser!.uid;

  final Stream<QuerySnapshot> _usersStream =
      FirebaseFirestore.instance.collection('Users')
        .doc(_uid)
        .collection('UserData')
        .snapshots();

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
       key: Key(_uid),
      stream: _usersStream,
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return const Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Text("Loading");
        }

        return ListView(
          children: snapshot.data!.docs
              .map((DocumentSnapshot document) {
                Map<String, dynamic> data =
                    document.data()! as Map<String, dynamic>;
                return ListTile(
                  title: Text(data['full_name']),
                  subtitle: Text(data['company']),
                );
              })
              .toList()
              .cast(),
        );
      },
    );
  }
}

我看到这个问题在SO上问了好几次,但我找不到一个好的解决方案。我试图在StreamBuilder中添加一个唯一的键,但它没有解决问题。
我也看到了didUpdateWidget的用法,但我不知道如何使用它。

qv7cva1a

qv7cva1a1#

请尝试替换以下内容:

final _uid = FirebaseAuth.instance.currentUser!.uid;

与此:

late final _uid;
  @override
  initState() {
  _uid = FirebaseAuth.instance.currentUser!.uid;
  super.initState();
 }

然后重新启动应用程序,模拟您的行为

llew8vvj

llew8vvj2#

使用以下内容重新加载当前用户详细信息:

await FirebaseAuth.instance.currentUser!.reload();

我会说,最好的地方,把它,是这样做之前,返回流,首先使流的一个方法:

Stream<QuerySnapshot> myStream() async {
await FirebaseAuth.instance.currentUser!.reload();
final _uid = FirebaseAuth.instance.currentUser!.uid;
return FirebaseFirestore.instance.collection('Users')
    .doc(_uid)
    .collection('UserData')
    .snapshots();
}

然后在StreamBuilder中,将stream属性设定为:

stream: myStream(),
0sgqnhkj

0sgqnhkj3#

我找到了解决办法:
我只是简单地移动了构建内部的流,问题就解决了!
编辑后:

class UserInformation extends StatefulWidget {
  @override
  _UserInformationState createState() => _UserInformationState();
}

class _UserInformationState extends State<UserInformation> {

  @override
  Widget build(BuildContext context) {

 final _uid = FirebaseAuth.instance.currentUser!.uid;

  final Stream<QuerySnapshot> _usersStream =
      FirebaseFirestore.instance.collection('Users')
        .doc(_uid)
        .collection('UserData')
        .snapshots();

    return StreamBuilder<QuerySnapshot>(
       key: Key(_uid),
      stream: _usersStream,
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return const Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Text("Loading");
        }

        return ListView(
          children: snapshot.data!.docs
              .map((DocumentSnapshot document) {
                Map<String, dynamic> data =
                    document.data()! as Map<String, dynamic>;
                return ListTile(
                  title: Text(data['full_name']),
                  subtitle: Text(data['company']),
                );
              })
              .toList()
              .cast(),
        );
      },
    );
  }
}

相关问题