我如何在flutter中将多个图像上传到firebase并获取它们的所有下载网址

问题描述 投票:0回答:5

这是我的上传功能。我想要的输出是所有网址的列表,但它返回一个空列表。我尝试了不同的建议解决方案,但都失败了。

Future<List<String>> uploadFiles(List _images) async {
  List<String> imagesUrls=[];

   _images.forEach((_image) async{
    StorageReference storageReference = FirebaseStorage.instance
        .ref()
        .child('posts/${_image.path}');
    StorageUploadTask uploadTask = storageReference.putFile(_image);
    await uploadTask.onComplete;

     imagesUrls.add(await storageReference.getDownloadURL());
     
  });
print(imagesUrls);
return imagesUrls;
}
firebase flutter dart firebase-storage
5个回答
16
投票

我认为你需要

Future.wait
来确保所有的未来都在继续之前得到解决:

Future<List<String>> uploadFiles(List<File> _images) async {
  var imageUrls = await Future.wait(_images.map((_image) => uploadFile(_image)));
  print(imageUrls);
  return imageUrls;
}

Future<String> uploadFile(File _image) async {
  StorageReference storageReference = FirebaseStorage.instance
      .ref()
      .child('posts/${_image.path}');
  StorageUploadTask uploadTask = storageReference.putFile(_image);
  await uploadTask.onComplete;

  return await storageReference.getDownloadURL();
}

3
投票

这个不起作用。它会直接返回,而不等待 foreach 循环完成。您可以使用以下代码:

Future<List<String>> uploadImages(List<File> images) async {
if (images.length < 1) return null;

List<String> _downloadUrls = [];

await Future.forEach(images, (image) async {
  Reference ref = FirebaseStorage.instance
      .ref()
      .child('jobPost')
      .child(getFileName(path: image));
  final UploadTask uploadTask = ref.putFile(image);
  final TaskSnapshot taskSnapshot = await uploadTask.whenComplete(() {});
  final url = await taskSnapshot.ref.getDownloadURL();
  _downloadUrls.add(url);
});

return _downloadUrls;
}

您可以访问this了解原因。


2
投票

试试这个

Future<List<String>> uploadFiles(List _images) async {
  List<String> imagesUrls=[];

   _images.forEach((_image) async{
    StorageReference storageReference = FirebaseStorage.instance
        .ref()
        .child('posts/${_image.path}');
    StorageUploadTask uploadTask = storageReference.putFile(_image);
    

     imagesUrls.add(await (await uploadTask.onComplete).ref.getDownloadURL());
     
  });
print(imagesUrls);
return imagesUrls;
}

如何使用:

List<String> urls = Future.wait(uploadFiles(_images));

1
投票

有完整的例子你可以明白

import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
import 'package:path/path.dart' as Path;

class AddImage extends StatefulWidget {
  @override
  _AddImageState createState() => _AddImageState();
}

class _AddImageState extends State<AddImage> {
  bool uploading = false;
  double val = 0;
  CollectionReference imgRef;
  firebase_storage.Reference ref;

  List<File> _image = [];
  final picker = ImagePicker();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Add Image'),
          actions: [
            FlatButton(
                onPressed: () {
                  setState(() {
                    uploading = true;
                  });
                  uploadFile().whenComplete(() => Navigator.of(context).pop());
                },
                child: Text(
                  'upload',
                  style: TextStyle(color: Colors.white),
                ))
          ],
        ),
        body: Stack(
          children: [
            Container(
              padding: EdgeInsets.all(4),
              child: GridView.builder(
                  itemCount: _image.length + 1,
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisCount: 3),
                  itemBuilder: (context, index) {
                    return index == 0
                        ? Center(
                            child: IconButton(
                                icon: Icon(Icons.add),
                                onPressed: () =>
                                    !uploading ? chooseImage() : null),
                          )
                        : Container(
                            margin: EdgeInsets.all(3),
                            decoration: BoxDecoration(
                                image: DecorationImage(
                                    image: FileImage(_image[index - 1]),
                                    fit: BoxFit.cover)),
                          );
                  }),
            ),
            uploading
                ? Center(
                    child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Container(
                        child: Text(
                          'uploading...',
                          style: TextStyle(fontSize: 20),
                        ),
                      ),
                      SizedBox(
                        height: 10,
                      ),
                      CircularProgressIndicator(
                        value: val,
                        valueColor: AlwaysStoppedAnimation<Color>(Colors.green),
                      )
                    ],
                  ))
                : Container(),
          ],
        ));
  }

  chooseImage() async {
    final pickedFile = await picker.getImage(source: ImageSource.gallery);
    setState(() {
      _image.add(File(pickedFile?.path));
    });
    if (pickedFile.path == null) retrieveLostData();
  }

  Future<void> retrieveLostData() async {
    final LostData response = await picker.getLostData();
    if (response.isEmpty) {
      return;
    }
    if (response.file != null) {
      setState(() {
        _image.add(File(response.file.path));
      });
    } else {
      print(response.file);
    }
  }

  Future uploadFile() async {
    int i = 1;

    for (var img in _image) {
      setState(() {
        val = i / _image.length;
      });
      ref = firebase_storage.FirebaseStorage.instance
          .ref()
          .child('images/${Path.basename(img.path)}');
      await ref.putFile(img).whenComplete(() async {
        await ref.getDownloadURL().then((value) {
          imgRef.add({'url': value});
          i++;
        });
      });
    }
  }

  @override
  void initState() {
    super.initState();
    imgRef = FirebaseFirestore.instance.collection('imageURLs');
  }
}

0
投票

未来 uploadFile() 异步 { 整数 i = 1;

for (var img in _image) {
  setState(() {
    val = i / _image.length;
  });
© www.soinside.com 2019 - 2024. All rights reserved.