Firebase Storage claims here in its iOS documentation that it
performs uploads and downloads regardless of network quality. Uploads and downloads are robust, meaning they restart where they stopped
so one would expect it to handle a loss of connection when uploading, but it doesn't seem to.
With the following Swift code in iOS, I am able to perform an upload just fine when there is a connection, but if the device doesn't have a connection or if it is ever disconnected from the network it goes to the failure condition.
let storage = FIRStorage.storage().referenceForURL("VALID_URL_REMOVED")
let imagesRef = storage.child("images/test.jpg")
let data = UIImageJPEGRepresentation(observationImage!, 0.7);
let uploadTask = imagesRef.putData(data!, metadata: nil)
uploadTask.observeStatus(.Progress) { snapshot in
// Upload reported progress
if let progress = snapshot.progress {
let percentComplete = 100.0 * Double(progress.completedUnitCount) / Double(progress.totalUnitCount)
print("percent \(percentComplete)")
}
}
uploadTask.observeStatus(.Success) { snapshot in
// Upload completed successfully
print("success")
}
uploadTask.observeStatus(.Failure) { snapshot in
print("error")
print(snapshot.error?.localizedDescription)
}
The debug output for this code is as follows.
/*
percent 0.0
percent 0.0044084949781492
2016-06-30 11:49:16.480 Removed[5020:] <FIRAnalytics/DEBUG> Network status has changed. Code, status: 1, Disconnected
percent 0.0044084949781492
error
Optional("An unknown error occurred, please check the server response.")
*/
Firebase's Real Time Database offline storage is also set up with the following code, but I'm unsure of whether this is related.
FIRDatabase.database().persistenceEnabled = true
I have also tried manually setting the timeout as mentioned in the answers to this question using the following lines, with no change.
let config = FIRStorage()
config.maxUploadRetryTime = 1000000
Is there a way to have it handle these disconnects without implementing the functionality from scratch? Am I missing something?
You are missing observers. Right now you only observe .success and .failure events. Try add observers for .resume, .pause, .progress to handle different events.
// Listen for state changes, errors, and completion of the upload.
uploadTask.observe(.resume) { snapshot in
// Upload resumed, also fires when the upload starts
}
uploadTask.observe(.pause) { snapshot in
// Upload paused
}
uploadTask.observe(.progress) { snapshot in
// Upload reported progress
let percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount)
/ Double(snapshot.progress!.totalUnitCount)
}
uploadTask.observe(.failure) { snapshot in
if let error = snapshot.error as? NSError {
switch (FIRStorageErrorCode(rawValue: error.code)!) {
case .objectNotFound:
// File doesn't exist
break
case .unauthorized:
// User doesn't have permission to access file
break
case .cancelled:
// User canceled the upload
break
/* ... */
case .unknown:
// Unknown error occurred, inspect the server response
break
default:
// A separate error occurred. This is a good place to retry the upload.
break
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With