【问题标题】:Flutter Upload batch of images and get all those URLs to store in FirestoreFlutter 上传一批图像并获取所有这些 URL 以存储在 Firestore 中
【发布时间】:2019-04-10 12:07:24
【问题描述】:

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

代码:

_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);
        }
      });
    });
  }

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我尝试了标记的答案对我不起作用,所以我深入挖掘并设法用 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查看更多信息

      【讨论】:

        【解决方案3】:

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

        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;
        }
        

        【讨论】:

        • 如果你使用 multi_image_picker,asset.release 会被移除。引用插件 change_log “删除了 Asset.releaseThumb、Asset.releaseOriginal 和 Asset.release 方法,因为它们不再需要。”
        • 我认为最好使用多个文件名
        【解决方案4】:

        试试这个(在 onComplete 内):

        storeRef.getDownloadURL() 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-02-12
          • 2021-07-23
          • 2020-04-14
          • 2021-03-23
          • 1970-01-01
          • 2020-10-29
          • 2017-05-11
          相关资源
          最近更新 更多