Flutter上载一批图像并获取所有这些URL存储在Firestore中

时间:2018-11-07 03:05:46

标签: firebase dart flutter google-cloud-firestore firebase-storage

我正在尝试将n张照片上传到Firebase存储并将这些URL保存在Firestore中的数组中,但是我无法获得downloadURL(),或者我不知道该在哪里找到它。我检查了其他答案,但这些答案是针对单个文件的,我试图上传一批并将URL一起存储,而不是上传并存储到Firestore的URL,依此类推等等。

代码:

_uploadImages(String userID, String productID, List<File> images, Function onSuccess(List<String> imageURLs), Function onFailure(String e)) {
    List<String> imageURLs = [];
    int uploadCount = 0;

    StorageReference storeRef = FirebaseStorage.instance.ref().child('Products').child(userID).child(productID).child(uploadCount);
    StorageMetadata metaData = StorageMetadata(contentType: 'image/png');

    images.forEach((image) {
      storeRef.putFile(image, metaData).onComplete.then((snapshot) {
        STUCK AT THIS POINT SINCE THE SNAPSHOT DOESN'T SHOW THE URL OPTION...
        //imageURLs.add(snapshot. )
        uploadCount++;

        if (uploadCount == images.length) {
          onSuccess(imageURLs);
        }
      });
    });
  }

4 个答案:

答案 0 :(得分:1)

我尝试了标记答案对我不起作用,所以我深入研究并设法使用for循环

 List<File> _imageList = List();
//add selected images to list
 _imageList.add(_image);
      Future uploadMultipleImages() async {

    List<String> _imageUrls = List();




    try {
      for (int i = 0; i < _imageList.length; i++) {
        final StorageReference storageReference = FirebaseStorage().ref().child("multiple2/$i");

        final StorageUploadTask uploadTask = storageReference.putFile(_imageList[i]);

        final StreamSubscription<StorageTaskEvent> streamSubscription =
            uploadTask.events.listen((event) {
          // You can use this to notify yourself or your user in any kind of way.
          // For example: you could use the uploadTask.events stream in a StreamBuilder instead
          // to show your user what the current status is. In that case, you would not need to cancel any
          // subscription as StreamBuilder handles this automatically.

          // Here, every StorageTaskEvent concerning the upload is printed to the logs.
          print('EVENT ${event.type}');
        });

        // Cancel your subscription when done.
        await uploadTask.onComplete;
        streamSubscription.cancel();

        String imageUrl = await storageReference.getDownloadURL();
        _imageUrls.add(imageUrl); //all all the urls to the list
      }
      //upload the list of imageUrls to firebase as an array
      await _firestore.collection("users").document("user1").setData({
        "arrayOfImages": _imageUrls,
      });
    } catch (e) {
      print(e);
    }
  }

您可以从此github project

中查看更多信息

答案 1 :(得分:1)

这些解决方案不适用于firebase_storage:^ 5.0.1 as await uploadTask.onComplete;不再适用。如果您升级了应用,请提出其他解决方案。谢谢

答案 2 :(得分:0)

尝试此操作(在onComplete内部):

storeRef.getDownloadURL() 

答案 3 :(得分:0)

您可以使用此方法将多个文件上传到Firebase存储,其中List<Asset>资产是您的List<File>文件。

Future<List<String>> uploadImage(
      {@required String fileName, @required List<Asset> assets}) async {
    List<String> uploadUrls = [];

    await Future.wait(assets.map((Asset asset) async {
      ByteData byteData = await asset.requestOriginal();
      List<int> imageData = byteData.buffer.asUint8List();

      StorageReference reference = FirebaseStorage.instance.ref().child(fileName);
      StorageUploadTask uploadTask = reference.putData(imageData);
      StorageTaskSnapshot storageTaskSnapshot;

      // Release the image data
      asset.releaseOriginal();

      StorageTaskSnapshot snapshot = await uploadTask.onComplete;
      if (snapshot.error == null) {
        storageTaskSnapshot = snapshot;
        final String downloadUrl = await storageTaskSnapshot.ref.getDownloadURL();
        uploadUrls.add(downloadUrl);

        print('Upload success');
      } else {
        print('Error from image repo ${snapshot.error.toString()}');
        throw ('This file is not an image');
      }
    }), eagerError: true, cleanUp: (_) {
     print('eager cleaned up');
    });

    return uploadUrls;
}