首页 > 解决方案 > 使用 Flutter 从一个未来获取价值并在另一个未来使用它

问题描述

我有一个收藏夹收藏夹保存在用户收藏夹下。每个收藏文档都有一个包含 product_Id 的字段。我想检索这个 product_id 值并用它来查询另一个集合。第二个集合包含实际的产品文档。

检索收藏夹集合中的所有文档。接下来我该怎么做才能将 product_id 字段的值作为字符串获取?

  getIdsfromUserFavs(userId) async {
    var _favData = await _usersCollectionReference
        .doc(userId)
        .collection('favourites')
        .get();


  }

这是用于查询产品集合的第二种方法。此方法需要上面的字符串值才能成功进行查询。

  Future<QuerySnapshot<Object?>> queryFavsCollection(value) async {
    var _favedProducts = await _productsCollectionReference
        .where('prod_id', isEqualTo: value)
        .get();
    print(value);
    return _favedProducts;
  }

我在 UI 中使用了 futureBuilder。

这是我尝试过的一种方法(问题是我没有返回任何数据):

  getIdsfromUserFavs(userId) async {
    var _favData = await _usersCollectionReference
        .doc(userId)
        .collection('favourites')
        .get();

    var allData = _favData.docs.map((doc) => doc.data()).toList();
    allData.forEach((element) async {
      String value = element['prod_id'];
      print(value);
      await queryFavsCollection(value);
    });
  }


  Future<QuerySnapshot<Object?>> queryFavsCollection(value) async {
    var _favedProducts = await _productsCollectionReference
        .where('prod_id', isEqualTo: value)
        .get();
    print(value);
    return _favedProducts;
  }

我可以看到上述方法将 id 打印到控制台。但是 FutureBuilder 没有收到任何数据:

I/flutter ( 4628): 3nHHEWuCDXvbhYfT8ljY
I/flutter ( 4628): MptYFV1oXhflDYkdQyIP
I/flutter ( 4628): Fd2ntXyNVmjn0D6mG3RA

标签: flutterdart

解决方案


下面的函数将返回收藏夹中的所有数据

  Future<QuerySnapshot<Map<String, dynamic>>> getIdsfromUserFavs(userId) async {
    QuerySnapshot<Map<String, dynamic>> _favData = await _usersCollectionReference
    .doc(userId)
    .collection('favourites')
    .get();

    return _favData; // This will return all data of favourite collection
  }

之后,您可以返回所需数据列表,如下面的函数所示

  Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> queryFavsCollection(userId) async {
   // Will store data in this list so at the end we can return this
    List<QueryDocumentSnapshot<Map<String, dynamic>>> favData = [];     
    QuerySnapshot<Map<String, dynamic>> _favData =
        await getIdsfromUserFavs(userId);
    for (QueryDocumentSnapshot<Map<String, dynamic>> data in _favData.docs) {
      String value = data['prod_id'];
      QuerySnapshot<Map<String, dynamic>> _fav = await 
          _productsCollectionReference
          .where('prod_id', isEqualTo: value)
          .get();

      if (_fav.docs.isNotEmpty) {
        _fav.docs.forEach((element) {
          favData.add(element);
        });
      }
    }

    return favData;
  }

现在您可以使用 FutureBuilder 如下所示

FutureBuilder<List<QueryDocumentSnapshot<Map<String, dynamic>>>>(
      future: queryFavsCollection(userId),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return Text('Loading...');
        }
        return Text('you data');
      },
    );

为了更好的实践,请参考这个。这是来自颤振文档

"future 必须更早获得,例如在 State.initState、State.didUpdateWidget 或 State.didChangeDependencies 期间。在构造 FutureBuilder 时,不能在 State.build 或 StatelessWidget.build 方法调用期间创建。如果创建了 future与FutureBuilder同时,那么每次重建FutureBuilder的父级时,异步任务都会重新启动。”


推荐阅读