Search code examples
swiftfirebaseswiftuifirebase-storage

Firebase Storage getData cannot be awaited


My function ends before all data can be retrieved from the fire storage and returns empty. How can I get the data before returning?

Code:

func listItem() -> [imageitem]{
        let storage = Storage.storage()
        let storageRef = storage.reference().child("images/image")
        var array = [imageitem]()
        
        storageRef.listAll { (result, error) in
            if let error = error {
                print("error")
                print(error)
            }
            print("storagereference")
                result?.items.forEach({ StorageReference in
                    print(StorageReference)
                    print(StorageReference.name)

                    
                    StorageReference.getData(maxSize: 5*1024*1024) {data, error in
                        if error == nil && data != nil{
                            if let image = UIImage(data: data!){
                                    let element =  imageitem(title: StorageReference.name, image: Image(uiImage: image))
                                    array.append(element)
                                    print(array)
                            }
                        }
                    }
                })
            
            print("end",array)
        }
        return array
    }

Console:

storagereference
gs://proj-69776.appspot.com/images/image/gorilla.jpg
gorilla.jpg
gs://proj-69776.appspot.com/images/image/test.jpg
test.jpg
end []
[proj.ListView.imageitem(title: "test.jpg", image: SwiftUI.Image(provider: SwiftUI.ImageProviderBox<__C.UIImage>))]
[proj.ListView.imageitem(title: "test.jpg", image: SwiftUI.Image(provider: SwiftUI.ImageProviderBox<__C.UIImage>)), proj.ListView.imageitem(title: "gorilla.jpg", image: SwiftUI.Image(provider: SwiftUI.ImageProviderBox<__C.UIImage>))]

adding an await before the addData gives me an error
Cannot pass function of type '(StorageReference) async -> Void' to parameter expecting synchronous function type


Solution

  • You cannot return data that is loaded asynchronously with a return statement like that, because the return runs well before you ever append any element to the array. If you set breakpoints and run the code in a debugger you can most easily validate that.

    Instead, you'll want to pass in a closure/callback or use a dispatch queue to get the value out of your function into the calling context.

    For examples of how to do this, see: