[英]Updating a StreamBuilder with new data in Flutter and 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.