Firebase 颤振-接收并修改流中的数据
我正在尝试执行以下操作:Firebase 颤振-接收并修改流中的数据,firebase,flutter,google-cloud-firestore,stream-builder,Firebase,Flutter,Google Cloud Firestore,Stream Builder,我正在尝试执行以下操作: 侦听Firestore流,以便在添加新文档时,StreamBuilder将接收、修改并呈现该文档 “修改”获取包含Firestore UID的流数据,使用该UID从Firestore获取数据,然后用该数据填充StreamBuilder 因此,流程是:添加新文档->流获取文档->函数从该文档获取UID->函数使用该UID从Firestore获取更多数据->函数返回用新数据填充StreamBuilder 我目前的设置如下——这是可行的,但FutureBuilder显然是在每
上游;
void initState(){
super.initState();
上游=aStream();
}
流aStream(){
返回Firestore.instance
.collection('FirstLevel')
.文档(ownUID(与流无关))
.collection('SecondLevel')
.快照();
}
未来processStream(列表流数据)异步{
List futureData=List();
用于(streamData中的var文档){
Map dataToReturn=Map();
DocumentSnapshot userDoc=等待Firestore.instance
.collection('FirstLevel')
.文档(流中其他用户的UID)
.get();
dataToReturn['i']=userDoc['i'];
futureData.add(dataToReturn);
}
返回未来数据;
}
...
...
//实际的小部件
扩大(
孩子:StreamBuilder(
溪流:上游,
生成器:(上下文,快照){
//错误/空处理
回归未来建设者(
未来:processStream(快照、数据、文档),
生成器:(上下文,futureSnap){
//错误/空处理
返回ListView.builder(
收缩膜:对,
itemCount:futureSnap.data.length,
滚动方向:轴垂直,
itemBuilder:(上下文,索引){
//继续填充
});
});
}),
),
处理这种流的最佳方法是什么?创建一个方法,其中来自Firestore流的数据被修改,然后返回,而根本不需要ListView.builder
编辑:我尝试创建自己的流,如下所示:
Stream<Map<String, dynamic>> aStream2() async* {
QuerySnapshot snap = await Firestore.instance
.collection(FirstLevel)
.document(OWN UID)
.collection(SecondLevel)
.getDocuments();
for (var doc in snap.documents) {
Map<String, dynamic> data = Map<String, dynamic>();
DocumentSnapshot userDoc = await Firestore.instance
.collection(FirstLevel)
.document(OTHER USERS UID RECEIVED FROM STREAM)
.get();
data['i'] = userDoc['i'];
yield data;
}
}
流aStream2()异步*{
QuerySnapshot snap=wait Firestore.instance
.收集(一级)
.文档(自己的UID)
.收集(二级)
.getDocuments();
用于(管理单元文档中的var文档){
地图数据=地图();
DocumentSnapshot userDoc=等待Firestore.instance
.收集(一级)
.文档(从流接收的其他用户UID)
.get();
数据['i']=userDoc['i'];
产量数据;
}
}
但是,当新文档添加到第二级集合时,流不会被触发/更新。好的,我想我找到了解决方案的路径。我从流中获取数据,对其进行修改,然后在一个方法中将其交给StreamBuilder,而不再需要FutureBuilder。正如克里斯托弗·摩尔(Christopher Moore)在评论中提到的那样,关键在于
等待。stream方法如下所示:
Stream<Map<String, dynamic>> aStream2() async* {
QuerySnapshot snap = await Firestore.instance
.collection(FirstLevel)
.document(OWN UID)
.collection(SecondLevel)
.getDocuments();
for (var doc in snap.documents) {
Map<String, dynamic> data = Map<String, dynamic>();
DocumentSnapshot userDoc = await Firestore.instance
.collection(FirstLevel)
.document(OTHER USERS UID RECEIVED FROM STREAM)
.get();
data['i'] = userDoc['i'];
yield data;
}
}
Stream()异步流*{
List DATATORETRETURN=List();
Stream=Firestore.instance
.收集(一级)
.文档(自己的UID)
.收集(二级)
.快照();
等待(QuerySnapshot q在流中){
对于(q.documents中的var文档){
Map dataMap=Map();
DocumentSnapshot userDoc=等待Firestore.instance
.collection('UserData')
.document(doc[“其他用户数据变量])
.get();
dataMap['i']=userDoc['i'];
//...//
dataToReturn.add(dataMap);
}
产生数据返回;
}
}
然后,StreamBuilder会按照我的要求填充修改后的数据。我发现自己正在使用这个工具,在我的应用程序中使用Dash聊天软件包实现一个聊天系统。我认为在流上使用map函数可能会更干净一些,下面是一个示例:
Stream<List<ChatMessage>> getMessagesForConnection(
String connectionId) {
return _db
.collection('connections')
.doc(connectionId)
.collection('messages')
.snapshots()
.map<List<ChatMessage>>((event) {
List<ChatMessage> messages = [];
for (var doc in event.docs) {
try {
messages.add(ChatMessage.fromJson(doc.data()));
} catch (e, stacktrace) {
// do something with the error
}
}
return messages;
});}
流getMessagesForConnection(
字符串连接ID){
返回_db
.collection('连接')
.doc(连接ID)
.collection('消息')
.快照()
.map((事件){
列表消息=[];
for(event.docs中的var doc){
试一试{
messages.add(ChatMessage.fromJson(doc.data());
}捕获(e,堆栈跟踪){
//对这个错误做点什么
}
}
返回消息;
});}
您可以通过使用async*
和wait for
从头开始创建流来实现这一点。你可以阅读更多关于这个的信息。谢谢。我确实尝试将流更改为自定义,并为StreamBuilder生成修改后的结果,但在将文档添加到Firestore集合时遇到了无法触发流的问题(因为StreamBuilder是由从自定义流返回的列表流提供的,而不是像我提供的示例中那样从Firestore本身)。我是否看错了这个流?