我有一个从firebase读取用户数据的流。我在登录后触发它,它工作得很好。我把数据显示在我的appbar上。当我手动更新firebase时,我想在appbar上立即看到新的日期。首先,我猜测是我的appbar出了问题,但是我注意到当我更新firebase数据时,我的流没有被触发。这是我的流代码片段。我缺了什么?
static Future<User> userDataStream(userID) async {
print("userDataStream");
final databaseReference = Firestore.instance;
User currentUser = User();
await for (var snapshot in databaseReference
.collection('users')
.where('userID', isEqualTo: userID)
.snapshots()) {
currentUser.userName = snapshot.documents.first.data['userName'];
currentUser.email = snapshot.documents.first.data['email'];
currentUser.userID = snapshot.documents.first.data['userID'];
currentUser.level = snapshot.documents.first.data['level'];
currentUser.balance = snapshot.documents.first.data['balance'];
print(currentUser.balance);
return currentUser;
}
return currentUser;
}
你如何使用这个流很重要。await for
开始监听用户,然后你做 return currentUser;
中,并打破 await for
. 因此,它不能在未来继续听流。
取而代之的是 return currentUser;
里面 await for
,你可以做这样的事情 setState((){this.renderedUser = currentUser;})
这样从服务器来的用户就变成了渲染的用户。如果你这样做,也可以添加 if (!mounted) return;
里面 await for
以便您在意识到自己处于不同的屏幕中时停止收听。
一个更好的选择可能是使用 StreamBuilder
小组件。
如果您运行当前的代码,并对数据库进行更改,则会出现以下情况 print
语句应该再次运行。这是因为 snapshots
已经在监听数据库的变化,并在这些变化发生时调用你的代码。
问题是,你返回一个 Future<User>
而一个未来只能解析(获取一个值)一次。如果你想返回实时数据,那将是一个 Stream<User>
(通常是一个 StreamBuilder
而非 FutureBuilder
以此来构建一个UI)。)