Home > Mobile >  how to show circular progress indicator while uploading multiple images to firebase using two screen
how to show circular progress indicator while uploading multiple images to firebase using two screen

Time:06-13

i am making a house management app i have to upload images of the property alongside other data related to the property so i am using two screens one for the general info about the house and the second one specifically to upload images

Form screen

enter image description here

Image Upload Screen

enter image description here

from the upload screen i am returning back a list of images to the form screen

// i am waiting for the list in the form screen
images = await Navigator.push(context, MaterialPageRoute(builder: (context) => AddPictures()));

// i am returning the list back from the upload screen
Navigator.pop(context,imageStrings);

I am failing to show circular progress indicator for some reason beyond my capacity to know itried all ways i know

this is the rest of the code

//outiside the widdget build i have two lists
List<XFile> imagesXFiles = []; //for raw image files from the gallery or camera 
List<String> imageStrings = []; //for image links from the firebase storage 

body: isLoading == true ? CircularProgressIndicator() : Column(
        children: [
          Expanded(
            //the first grid is a button to let the user access camera or gallery
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 3,
                  crossAxisSpacing: 2.0,
                  mainAxisSpacing: 2.0
              ),
              itemCount: imagesXFiles.length   1,
              itemBuilder: (BuildContext context, int index) {
                return index == 0 ? GestureDetector(
                  onTap: (){
                    // a function to pick images and add store them to the list "imagesXFiles"
                    _showPicker(context);
                  },
                  child: Container(
                    decoration: BoxDecoration(
                      color: Colors.black12,
                      borderRadius: BorderRadius.circular(5.0),
                    ),
                    child: Icon(
                      Icons.add,
                      color: Colors.black,
                      size: 30.0,
                    ),
                  ),
                ): Container(
                  child: Image(
                      image: FileImage(File(imagesXFiles[index-1].path)),
                      fit: BoxFit.fill
                  ),
                );
              },
            ),
          ),
          TextButton(
              onPressed: ()async{
                // for some reason the circular progress doesn't work i dont understand why 
                setState(() {
                  isLoading = true;
                });
                imageStrings = await uploadImages(imagesXFiles).whenComplete(() {
                  setState(() {
                    isLoading = false;
                    Navigator.pop(context,imageStrings);
                  });

                });
              },
              child: Text("Upload",style: TextStyle(color: Colors.black,fontSize: 25),)),
        ],
      ),

here is the upload function that uploads the images to firebase

Future<List<String>> uploadImages(List<XFile> imagesXFiles) async {

   imagesXFiles.forEach((image) async {
    final storageRef = storage.ref().child(Random().nextInt(100).toString());
    await storageRef.putFile(File(image.path));
    String imageURL = await storageRef.getDownloadURL();

    imageStrings.add(imageURL);
    firebaseFirestore
        .collection("housePictures")
        .add({
      "imageURL" : imageURL,
    });
  });

  return imageStrings;

}

CodePudding user response:

You can’t use forEach statement in a async operation. It is not going to wait. Use a normal for statement. Example: for(var item in items) etc. That should fix your issue. If you really want to use a for each you need to use Future.foreach see this thread -> How to Async/await in List.forEach() in Dart

CodePudding user response:

You can use forEach with Future as below.

await Future.forEach(imagesXFiles, (image) async {
    final storageRef = storage.ref().child(Random().nextInt(100).toString());
    await storageRef.putFile(File(image.path));
    String imageURL = await storageRef.getDownloadURL();

    imageStrings.add(imageURL);
    FirebaseFirestore.instance
        .collection("housePictures")
        .add({
            "imageURL" : imageURL,
         });
});
  • Related