await async function on forEach Loop

252 views
Skip to first unread message

Jeremy West

unread,
Sep 6, 2020, 12:09:35 AM9/6/20
to Flutter Development (flutter-dev)
Hi There,

I am trying to upload a Asset List of images to Firebase Storage with a forEach loop, however only the first image of the List ever gets uploaded. I am super new to Flutter, just tying to make a quick app for internal use to assist our media & marketing teams.

I have a button that calls a function with the loop:
onPressed: () {
uploadImages(images);
}

Then the function with the loop, I have added await for the uploadImage function to complete before sending the next Asset in the List:
Future<void> uploadImages(images) async {
await Future.forEach(images, (images) async {
await saveImage(images);
});
}

Finally the saveImage function that should send the image to Firebase (which it does but only 1 image):
Future saveImage(Asset asset) async {
ByteData byteData = await asset.getByteData();
List<int> imageData = byteData.buffer.asUint8List();
StorageReference ref =
FirebaseStorage.instance.ref().child("$now " + "$displayName.jpg");
StorageUploadTask uploadTask = ref.putData(imageData);
return await (await uploadTask.onComplete).ref.getDownloadURL();
}

Can someone please point out where I might be going wrong with my uploadImage function causing only a single image to ever get uploaded?

Thanks!

Suzuki Tomohiro

unread,
Sep 6, 2020, 10:17:40 AM9/6/20
to Jeremy West, Flutter Development (flutter-dev)
1. Can you declare all variables with their types (especially the function arguments)?

2. Learn how to use debugger to set breakpoints.

--


You received this message because you are subscribed to the Google Groups "Flutter Development (flutter-dev)" group.


To unsubscribe from this group and stop receiving emails from it, send an email to flutter-dev...@googlegroups.com.


To view this discussion on the web visit https://groups.google.com/d/msgid/flutter-dev/5967c940-765d-4c11-a08e-44b8a8540dfen%40googlegroups.com.


Jeremy West

unread,
Sep 6, 2020, 10:22:10 AM9/6/20
to Flutter Development (flutter-dev)
Yep, so I have updated the loop from a forEach to a for loop:
onPressed: () async {
for (var i = 0; i < images.length; i++) {
await saveImage(images[i]);
}
//uploadImages(images);
}

However, inspecting with debugger, I believe the issue is on the return from the uploadImages function, the specific error is:
error: org-dartlang-debug:synthetic_debug_expression:1:1: Error: The getter 'downloadURL' isn't defined for the class '_ImagePickerState'.
 - '_ImagePickerState' is from 'package:google_login/views/image_picker.dart' ('lib/views/image_picker.dart').
Try correcting the name to the name of an existing getter, or defining a getter or field named 'downloadURL'.
downloadURL
^^^^^^^^^^^

I found a stackoverflow issue that references the exact same problem, I updated the firebase upload function to the accepted solution, which still returns the same error unfortunately. I believe this is the root cause of the loop failing to continue: https://stackoverflow.com/questions/51328368/how-to-upload-image-to-firebase-using-flutter

My uploadImage function is now:
Future<String> saveImage(Asset i) async {
ByteData byteData = await i.getByteData();
List<int> imageData = byteData.buffer.asUint8List();
StorageReference ref =
FirebaseStorage.instance.ref().child("$now " + "$displayName.jpg");
StorageUploadTask uploadTask = ref.putData(imageData);
return (await uploadTask.onComplete).ref.getDownloadURL();}

So I guess the question is now not so much the for loop but how to resolve the downloadURL error?

Suzuki Tomohiro

unread,
Sep 6, 2020, 10:29:35 AM9/6/20
to Jeremy West, Flutter Development (flutter-dev)
Can you declare variables for this line? I expect 3 variables.

 (await uploadTask.onComplete).ref.getDownloadURL()


Jeremy West

unread,
Sep 6, 2020, 10:28:00 PM9/6/20
to Flutter Development (flutter-dev)
Yep ok, resolved that - I now get the download URL returned and the function completes.

The for loop does not run again though, unfortunately it still only uploads a single image and does not return to the next asset in the array.

Suzuki Tomohiro

unread,
Sep 6, 2020, 11:28:47 PM9/6/20
to Flutter Development (flutter-dev)
Add “print” for the return value of saveImage.
It should show multiple URLs if assets are more than one.

Jeremy West

unread,
Sep 7, 2020, 2:44:22 AM9/7/20
to Flutter Development (flutter-dev)
Thanks for your help, through a process of troubleshooting I found the loop itself was actually working, but my function to give the files unique names was causing the first image to get overwritten by the second when the loop ran!!

School boy error - its working well now, thanks again :)
Reply all
Reply to author
Forward
0 new messages