I have a problem with the Firebase SDK for iOS in swift 2. Im trying to set a picture to a downloaded from the Firebase storage. When I call the function it gives back nil. I think its because the download task provided by the Firebase sdk is asynchron, so when the return state meant is called the uid which is necessary isn't set because the Task isn't finished. How can I solve this so I get the right picture returned?
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = downloadProfilePicFirebase()
}
The Firebase download function:
func downloadProfilePicFirebase() -> UIImage{
print("download called")
//local paths
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentDirectorPath:String = paths[0]
let imagesDirectoryPath = documentDirectorPath.stringByAppendingString("/profiles")
var uid = String()
if let user = FIRAuth.auth()?.currentUser {
let uid = user.uid
let storageRef = FIRStorage.storage().referenceForURL("gs://myid.appspot.com")
let profilePicRef = storageRef.child("/profile_pic.jpg")
let homeDir: NSURL = NSURL.fileURLWithPath(NSHomeDirectory())
let fileURL: NSURL = homeDir.URLByAppendingPathComponent("Documents").URLByAppendingPathComponent("profiles").URLByAppendingPathComponent("profile_pic").URLByAppendingPathExtension("jpg")
// Download to the local filesystem
let downloadTask = profilePicRef.writeToFile(fileURL) { (URL, error) -> Void in
if (error != nil) {
print(error)
} else {
// svaed localy now put in ImageView
}
}
}
return UIImage(contentsOfFile: "\(imagesDirectoryPath)"+"/profile_pic_user_"+uid+".jpg")!
}
Firebase is asynchronous as you mentioned so let it drive the flow of data within your app.
Don't try to return data from a Firebase block - let the block handle the returned data and then move to the next step once that data is valid within the block.
There's a couple of options:
One option is to populate your data from the .writeToFile completion handler
A second option is add an observer to the node and when that completes, populate your imageView