如何在 flutter 中从 Firebase 存储中获取相关图像

How to get the related image from Firebase storage in flutter

我正在尝试构建一个小部件列表,这些小部件使用 streambuilder 为我的云 Firestore 中的每个条目显示。这是代码:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class ProperHomeScreen extends StatefulWidget {


  @override
  _ProperHomeScreenState createState() => _ProperHomeScreenState();
}

class _ProperHomeScreenState extends State<ProperHomeScreen> {
  final _firestore = Firestore.instance;
  String _downloadURL;
  StorageReference _reference = FirebaseStorage.instance.ref();

  @override
  void initState() {
    super.initState();
  }


  void postsStream() async {
    await for (var snapshot in _firestore.collection('posts').snapshots()) {
      for (var post in snapshot.documents) {
        print(post.data);
      }
    }
  }

  testFunction(postImage) async {

      print('Here\'s the postImage data from test function: $postImage');
      String downloadAddress = await _reference.child(postImage).getDownloadURL();
      setState(() {
        _downloadURL = downloadAddress;
      });
      print('THIS IS THE DOWNLOAD URL FROM THE TEST FUNCTION! ::: $_downloadURL');

    }

   


  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: ListView(
          children: <Widget>[

            StreamBuilder<QuerySnapshot> (
              stream: _firestore.collection('posts').snapshots(),
              builder: (context, snapshot) {
                if(!snapshot.hasData) {
                  return Center(
                    child: CircularProgressIndicator(
                      backgroundColor: Colors.lightBlueAccent,
                    ),
                  );
                }
                  final posts = snapshot.data.documents;
                  List<Widget> postWidgets = [];
                  for (var post in posts)  {
                    final postText = post.data['questionOne'];
                    final postSender = post.data['email'];
                    final postImage = post.data['filePath'];

                    testFunction(postImage);

                    print('THIS IS THE DOWNLOAD ADDRESS : $_downloadURL');


                    final postWidget = Container(
                      child: Column(
                        children: <Widget>[
                          Text('$postText from $postSender with image : $postImage'),
                          Image.network('$_downloadURL'),
                        ],
                      ),
                    );
                    postWidgets.add(postWidget);
                  }
                  return Column(
                    children: postWidgets,
                  );

              },
            ),

          ],
        ),
      );
  }

}

在控制台中,它可以很好地打印 url,但我遇到的问题是它一直保持 运行 testFunction() 直到我停止 main.dart。

我正在尝试为每个post显示不同的图像。

本质上,我将数据保存在 Cloud firestore 中,并将图像保存在 firebase 存储中。我将图像的文件名存储在 Cloud Firestore 中,以便我可以访问它。

这是我如何在 firestore 中保存 post 的示例:

void submitPostSection() {
    DateTime now = DateTime.now();
    _firestore.collection('posts').add({
      'email': loggedInUser.email,
      'date': now,
      'questionOne': widget.questionOne, //this is a simple string. Example data: 'Here is the latest post today 31st July 2020'
      'filePath' : _filePath, // this is just the image name that its saved as in firebase storage. datatype for this is string. here's an example of the data: 'myimage2.jpg'
    });
  }

我认为问题是因为该方法不断被调用并设置 _downloadURL 的状态。我不太确定解决这个问题的最佳方法。

有什么想法吗?

提前致谢!

问题是在 testFunction() 中你正在调用 setState() 这将继续调用 build() 方法,你可以执行以下操作:

  List<String> listOfUrl = [];
  for (var post in posts)  {
    final postText = post.data['questionOne'];
    final postSender = post.data['email'];
    final postImage = post.data['filePath'];
    String downloadAddress = await _reference.child(postImage).getDownloadURL();
    listOfUrl.add(downloadAddress);
   }
ListView.builder(
        shrinkWrap: true,
        itemCount: listOfUrl.length,
        itemBuilder: (BuildContext context, int index) {
         return Card(
           child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
             children: <Widget>[
              Image.network(listOfUrl[index]),
                 ],
                ),
              );
           });

将 url 添加到列表中,然后使用列表视图显示它们。

我的问题已经解决了。我删除了 testFunction() 并将实际的 imageURL 保存在云 firestore 文档中。然后我可以通过添加以下行非常轻松地访问它:

final postImageUrl = post.data['imageURL'];