'How can i upload multiple images to firebase in flutter and get all their download urls
Here is my upload function. My desired output is a list of all urls, but it returns an empty list. I have tried different suggested solutions, but all of them have failed.
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;
}
Solution 1:[1]
I think you'll need Future.wait
to ensure all futures are resolved before continuing:
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();
}
Solution 2:[2]
Try this
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;
}
How to use this:
List<String> urls = Future.wait(uploadFiles(_images));
Solution 3:[3]
this not working. It will direct return without waiting for the foreach loop to be finished. You may use the code below:
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;
}
You may visit this to know what's the reason.
Solution 4:[4]
There is compile example you can get the idea
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');
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Henok |
Solution 2 | thien nguyen |
Solution 3 | liow |
Solution 4 | samad shukr |