dart Futurebuilder connectionState.done返回true,即使我的数据还没有准备好并返回null,数据可用后无法重建

92dk7w1h  于 2023-05-11  发布在  其他
关注(0)|答案(1)|浏览(132)

我一直在想办法但还是没找到。
我有一个streambuilder,它可以像这样提取用户最近的8个位置:

Stream<List<DocumentSnapshot>> stream() =>
geo.collection(collectionRef: ref).within(center: center, radius: radius, field: 'position').take(1);

下面是streambuilder,它将这8个位置作为一个列表返回,并基于此数据构建自己的卡片列表:

StreamBuilder<List<DocumentSnapshot>>(
  stream: _stream,
  builder: (context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
    if (snapshot.data != null) {
      List<DocumentSnapshot<Object?>>? streamList = snapshot.data?.toList();
        for (var i = 0; i < 8; i++) {
        print(i);
        var tester = streamList![i].id;
        varX.add(streamList![i]['xxx']);
        Test.add(tester);
        listNearby = List<String>.from(Test);
        
          if (i == 7) {
              Future.delayed(Duration.zero, () async {
              getFuture;
              });
           alreadyBuilt = 1;
          }
        }

      return SizedBox(///Here I display some information from that stream);
    } else {
        return SizedBox(///Here I display the loading information);
    }
}),

因此,这将返回一个'listNearby',我使用此列表以以下方式在不同的firebase数据库中提取8个其他文档ID:我遇到的一些问题-我不确定等待listNearby完成/从我的futureStream返回的正确方法。

Future pullData() async {
  if (listNearby.isNotEmpty) {
    var listNearbyReturn = [];
    var firestore = FirebaseFirestore.instance;
    for (var i = 0; i < 8; i++) {
      DocumentSnapshot gG = await firestore.collection('xxxx').doc(listNearby[i]).get();
      listTest.add(gG.data().toString());
      try {
        for (var x = 0; x < 3; x++) {
          ///I pull specific data I need from the snapshot.
          final incremDt = _now.add(Duration(days: x));
          final incremDtFrmtd = DateFormat('MM-dd-yyyy').format(incremDt);
          var regexp = RegExp(r"(?<=xx-).+?(?=:)");
          Iterable<Match> matches = regexp.allMatches(gG.get(incremDtFrmtd).toString(), 0);
          if (matches.isNotEmpty) {
            for (final Match h in matches) {
              ///other calculations
              listNearbyReturn.add({///Add some variables which I need to show a future card
                });
            }
          }
        }
      } catch (e) {
        print(e);
      }
    }
    listNearbyReturn((a, b) {
      int dateComp = a['date'].compareTo!(b['date']);
      if (dateComp == 0) {
        return parseTime(a['time'][0]).compareTo(parseTime((b['time'][0])));
      }
      return dateComp;
    });
    print('done');
    print(listNearbyReturn);
    return listNearbyReturn;
  } else {
    return null;
  }
}

这又回到了我的futurebuilder,可以在下面看到,尽管我有各种各样的问题。ConnectionState.done显示true/connected,尽管snapshot.data仍然为null,但它不应该等待非null响应吗?

FutureBuilder(
future: getFuture,
builder: (_, snapshot) {
print(snapshot.data);
if (snapshot.connectionState == ConnectionState.done) {
    print('connected');
    print('are we seeing null here? ${snapshot.data}'); //<==== YES, it is showing null? Why? It shouldn't connect until data is non null
return Container(
   height: 150,
    child: ListView.separated(///Here I build my listview),
);
}

if (snapshot.connectionState == ConnectionState.waiting) {
    print('waiting');
    return CircularProgressIndicator();
} else
    print('failed?');
    return CircularProgressIndicator();
});
)

我正在用下面的方式初始化我的FutureBuilder(至少现在是这样,在过去的几天里它已经改变了这么多)

class _HomescreenState extends State<FinderHomescreen> {
  late Future getFuture;
  final _stream = stream();

  @override
  void initState() {
    getGames();
    getFuture = pullData();
    super.initState();
  }

所以这里有几个问题,一些是为了证实我的理解,一些是为了看看我是否遗漏了一些显而易见的东西。我的整体问题如下:我需要我的streambuilder返回8个最接近用户的位置,然后将这些位置提供给一个列表,该列表将迭代从不同的firebase数据库中提取,以根据这8个位置(但存储在其他地方)提取不同的信息。这导致我的futurebuilder接受'null'作为响应,并使用null构建,一旦数据变得实际可用,就永远不会重建(只有热重载才会加载我的卡)。实现这一点的正确方法是什么?我也尝试过使用provider,但这会在重新收集数据时创建一个无限的重新加载循环,并重新构建小部件-重新构建树等...

tvz2xvvm

tvz2xvvm1#

如果其他人遇到这样的事情,我必须改变我如何将8个最近的位置发送到我的futurebuilder列表的逻辑:
我没有在streambuilder中返回列表listNearby,而是创建了一个新的future:

Future<List<DocumentSnapshot>> getClosestLocations() async {
  List<DocumentSnapshot> closestLocations = [];
  await for (List<DocumentSnapshot> documents in stream()) {
    closestLocations = documents;
    break;
  }
  return closestLocations;
}

然后在我的pullData中:

List<DocumentSnapshot> closestLocations = await getClosestLocations();

然后我重复了一遍。

相关问题