Flutter error : The argument type 'List<Future<Widget>>' can't be assigned to the parameter type 'List<Widget>'

Flutter error : The argument type 'List<Future<Widget>>' can't be assigned to the parameter type 'List<Widget>'

我正在尝试从 Firebase Firestore 中创建项目列表(已完成)并从 Firebase 云存储中为每个项目获取不同的图像 URL。

我使用名为 getPhotoUrl 的函数来更改变量 photoUrl 的值。问题是 returngetPhotoUrl 之前执行。如果我在函数 getPhotoUrl 前面添加 await 并在 [= 之后添加 async 35=]((document), 我得到一个错误说 参数类型 'List<Future>' 不能分配给参数类型 'List'.

我的代码:

class PhotosList extends StatefulWidget {
  @override
  _PhotosListState createState() => _PhotosListState();
}

class _PhotosListState extends State<PhotosList> {
  String photoUrl = 'lib/assets/default-image.png';
  List<DocumentSnapshot> _docs;

  getPhotoUrl(documentID) {
    Reference ref = storage
        .ref('Users')
        .child(currentUser.uid)
        .child('Photos')
        .child(documentID)
        .child('image_1.jpg');
    ref.getDownloadURL().then((value) {
      setState(() {
        photoUrl = value.toString();
      });
    }).catchError((e) {
      setState(() {
        print(e.error);
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: firestore
          .collection('Users')
          .doc(currentUser.uid)
          .collection('Photos')
          .orderBy('date')
          .snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (!snapshot.hasData) return CircularProgressIndicator();
        _docs = snapshot.data.docs;
        if (_docs.isEmpty)
          return Center(
              child: Text("The list is empty."));
        return Container(
          child: ResponsiveGridList(
            desiredItemWidth: 100,
            squareCells: true,
            minSpacing: 5,
            children: _docs.map((document) {
              getPhotoUrl(document.id);
              return PhotosListItem(photoUrl: photoUrl);
            }).toList(),
          ),
        );
      },
    );
  }
}

我认为你混合了两种不同的方式。在每个构建循环中,您映射您的文档并请求该 photoUrl,但在该方法中您调用 setState,它会重新触发您的构建方法。这样你应该在获取照片 url 和构建你的小部件的无限循环中结束。

您有三个选择:

  1. 加载你的 photoUrls 并将它们存储在你的小部件中 -> 调用设置状态 -> 如果你的照片已加载,请检查你的映射函数,如果是,则获取它,如果没有,调用你的 getPhotoUrl 函数
  2. 同步加载您的 photoUrls 并从您的函数 return url 并将其设置为您的 PhotosListItem
  3. (我更喜欢这个)将您的 documentId 添加到映射函数中的 photosListItem,并在您的项目中加载这张照片 url。在这个 PhotoListItem 中,您有一个带有 imageUrl 的变量,在 initState 中,您调用 getPhotoUrl 函数

在您的 PhotoItem 中:

  String imageUrl;
  
  @override
  void initState() {
    Future.delayed(Duration.zero, () {
      setState(() {
        // load your data and set it to your variable
        imageUrl = ..
      });
    });
    super.initState();
  }

您可能会使用 FutureBuilder,因为 StreamBuilder 似乎是同步的:

谢谢大家的回答,其实我找到了另一种解决方案,就是在将图像上传到存储后直接在 Firestore 中获取和写入 URL。

这篇文章对我帮助很大:https://medium.com/swlh/uploading-images-to-cloud-storage-using-flutter-130ac41741b2

(PS:一些 Firebase 名称自本文发布后发生了变化,但它仍然有用。)

此致。