簡體   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