繁体   English   中英

StreamBuilder 未更新 Flutter 中的 Firestore 数据

[英]StreamBuilder not updating Firestore data in Flutter

我正在制作一个 Flutter 应用程序,我正在尝试在应用程序中获取用户数据。

所以基本上,用户使用他的信息(姓名、email、密码)进行注册,当他登录时,这些数据会显示在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的使用,但我不明白如何使用它。

尝试替换这个:

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

有了这个:

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

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

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

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

我会说放置它的最佳位置是在返回 stream 之前执行此操作,首先使 Stream 成为一个方法:

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(),

我找到了解决方案:

我只是将 stream 移到构建中,问题就解决了!

编辑后:

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(),
        );
      },
    );
  }
}
```

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM