Firebase 颤振腹板(测试版)、Dart、Can和x27;t使用JSON Firestore包装插件完成异步未来函数-asyc,wait,Future

Firebase 颤振腹板(测试版)、Dart、Can和x27;t使用JSON Firestore包装插件完成异步未来函数-asyc,wait,Future,firebase,asynchronous,flutter,dart,google-cloud-firestore,Firebase,Asynchronous,Flutter,Dart,Google Cloud Firestore,我正在编写一个带有颤振的web应用程序(颤振web可在beta频道上获得),官方的、谷歌支持的Firebase库不支持颤振的web版本 我正在使用一个开源插件(这是难以置信的),作为Firebase的JSON端点功能的包装器。 插件: Future pullItems(int-zip、字符串键、int-index)异步{ 列表项列表=[]; final ref=store.collection(“供应商全球”).doc(“美国”).collection(zip.toString()).doc(k

我正在编写一个带有颤振的web应用程序(颤振web可在beta频道上获得),官方的、谷歌支持的Firebase库不支持颤振的web版本

我正在使用一个开源插件(这是难以置信的),作为Firebase的JSON端点功能的包装器。 插件:

Future pullItems(int-zip、字符串键、int-index)异步{
列表项列表=[];
final ref=store.collection(“供应商全球”).doc(“美国”).collection(zip.toString()).doc(key.collection(“项目”);
int i=0;
参考onSnapshot.listen((querySnapshot){
最终int snapSize=querySnapshot.size;
querySnapshot.forEach((字段){
var item=field.data();
print(key+”:“+field.id);//这将打印ea.key中的所有项,用于调试
Item itemObject=新项目(项目['name']);
itemList.add(itemObject);
i++;
如果(i==snapSize){//,则在
//完成之前的类似函数,父键来自何处。
返回项目列表;
}
});
});
返回项目列表;
}
问题似乎与.onSnapshot.listen((querySnapshot))有关,特别是.listen,它是一个开放连接。我见过这样的情况,即在对Firestore的一行调用中定义项目列表,以wait语句开始,以.map(()).toList()结束但是它使用的是标准的谷歌API,它似乎有更多的灵活性

Future<List<Item>> loadItems() async {
      final List<Item> itemList = (await Firestore.instance.collection('items').getDocuments()).documents.map((snapshot) => Item(doc['kode'], doc['name'])).toList();
      return itemList;
    }
Future loadItems()异步{
最终列表itemList=(等待Firestore.instance.collection('items').getDocuments()).documents.map((快照)=>Item(doc['kode'],doc['name'])).toList();
返回项目列表;
}

实际问题是,将来的函数会立即返回空白列表ItMeList= [];由于底部的返回。但是,如果我删除底部返回,它会发出警告,并且不会在该点计算。

是否有任何方法可以使用.onSnapshot listen功能遍历集合中的多个文档,并将它们作为列表返回


非常感谢您的任何意见,这让我沮丧了10多个小时

您需要的是使用一个
完成程序
…如果您熟悉它,这就像javascript中的承诺延迟一样。请查看:

Future<List<Item>> pullItems(int zip, String key, int index) {
    Completer<List<Item>> completer = Completer();
    List<Item> itemList = [];
    final ref = store.collection("vendors-global").doc("usa").collection(zip.toString()).doc(key).collection("items");
    int i = 0;
    ref.onSnapshot.listen((querySnapshot) {
      final int snapSize = querySnapshot.size;
    querySnapshot.forEach((field) {
      var item = field.data();
      print(key + " : " + field.id);     //this prints all the items in ea. key, for debugg
      Item itemObject = new Item(item['name']);
      itemList.add(itemObject);
      i++;
      if (i == snapSize) { //this counter is how I triggered this function off after a
                     //similar function before it finished, where the parent keys came from.
        completer.complete(itemList);
      }
      });
    });
  return completer.future;
}
Future pullItems(int-zip、字符串键、int-index){
Completer Completer=Completer();
列表项列表=[];
final ref=store.collection(“供应商全球”).doc(“美国”).collection(zip.toString()).doc(key.collection(“项目”);
int i=0;
参考onSnapshot.listen((querySnapshot){
最终int snapSize=querySnapshot.size;
querySnapshot.forEach((字段){
var item=field.data();
print(key+”:“+field.id);//这将打印ea.key中的所有项,用于调试
Item itemObject=新项目(项目['name']);
itemList.add(itemObject);
i++;
如果(i==snapSize){//,则在
//完成之前的类似函数,父键来自何处。
完成者。完成(项目列表);
}
});
});
返回completer.future;
}

请注意,我是如何从函数末尾删除
async
的。
async
用于在函数内部使用任何
wait
调用时自动为您创建
Future
。由于您使用的是回调而不是
wait
,因此您应该只使用
完成器
为您处理您的未来。它返回未来,并在
completer.complete(…)时触发任何等待其“完成”的代码
被调用。

for-each中的
return
语句没有达到预期效果。它只是从作为for-each参数传递的闭包函数返回,而不是从封闭函数返回。将for-each重构为类似于
for(querySnapshot中的var字段)的普通for循环{
返回语句将按预期工作。
Future<List<Item>> pullItems(int zip, String key, int index) {
    Completer<List<Item>> completer = Completer();
    List<Item> itemList = [];
    final ref = store.collection("vendors-global").doc("usa").collection(zip.toString()).doc(key).collection("items");
    int i = 0;
    ref.onSnapshot.listen((querySnapshot) {
      final int snapSize = querySnapshot.size;
    querySnapshot.forEach((field) {
      var item = field.data();
      print(key + " : " + field.id);     //this prints all the items in ea. key, for debugg
      Item itemObject = new Item(item['name']);
      itemList.add(itemObject);
      i++;
      if (i == snapSize) { //this counter is how I triggered this function off after a
                     //similar function before it finished, where the parent keys came from.
        completer.complete(itemList);
      }
      });
    });
  return completer.future;
}