Firebase and iOS
How to Upload Images to Cloud Storage for Firebase with Swift
Cloud Storage for Firebase is a great place for us to store users’ files. Uploading and downloading files to and from Cloud Storage is very simple and straightforward: Firebase provides a set of SDK for iOS, Android, Web, C++ and Unity developers to manage Cloud Storage for Firebase in an easy way. And it is easy for developers to restrict the access right to each file with Firebase Security Rules.
Below is a simple illustration of what we are going to build in this tutorial:
Getting Started
Please follow the official documentation to set up your Firebase project and enable Cloud Storage for Firebase using the Firebase console. Make sure you upgrade to the Blaze plan if your storage requirements exceed the 5GB free quota.
Building the UI
UIImagePickerController
is a special kind of UIViewController
which allows users to select photos or video clips from camera or album source. For demonstration purposes, I set the sourceType
to photoLibrary
and mediaTypes
to image file only. You can change them to other values for your own purpose, e.g. recording a video clip from a camera source.
We then need to implement both the UIImagePickerControllerDelegate
and UINavigationControllerDelegate
to handle the selected file information (file URL). We can then initiate uploading the file to Cloud Storage for Firebase on line 24.
To learn more aboutUIImagePickerViewController
, check out the following article:
Uploading Files to Cloud Storage for Firebase
We can divide the above codes into the below sessions:
- Line 6–7: Construct a unique file name to the file stored in Cloud Storage for Firebase. Please note that new files will overwrite the original file if the file names are the same.
- Line 9: Create a Storage reference with the filename. We can also store it inside a “folder” if you like. “Folder” is only a human-readable term, as there are no directory in Cloud Storage. Files have no hierarchical relationship.
Reference: Cloud Storage Object Name Documentation - Line 10–26: Upload the file data along with its metadata. After a successful upload, we can fetch the download URL of the uploaded image and then fetch it with any image loader, e.g. Kingfisher.
Handling errors
There could be errors during uploading files to Cloud Storage for Firebase at both server and client sides. We can handle the errors with the observe
function. Here are some common errors:
- Violation of Cloud Storage Security Rules
Firebase server can reject any read and write operations based on the security rules. For example, the only logged-in user may upload files:
2. Network connection error
Network stability is sometimes an issue on the client-side. For example, during underground transportation or inside a lift.
3. Free quota is exceeded
According to the Firebase pricing, there is a 5GB free quota for projects on the Spark Plan. The project owner has to upgrade to Blaze Plan in order to have larger storage.
4. Cancelled by user
Singleton Nature —✖️ UIViewController Lifecycle
Uploading a file to the Cloud server can be a long-running operation depending on the user’s network condition (and the file size). Sometimes, users probably like to navigate to another screen during the uploading task.
🤔 Do you think users must stay on the upload screen until the upload has finished?
The answer is “no”.
SDK has taken care of this situation by using a singleton pattern. The Storage
instance returned from Storage.storage()
is a singleton, which lives as long as the app lives. Therefore, the uploading task is still running in the background even the user has exited the page for uploading files.
Your 2nd question probably is “How can we handle the event (completion or error) of the uploading task when the user has navigate to a different screen?”
One way to do this is to use the Notification center:
At the callback of the putData
, we can enclose the storageMetaData
and error
into a dictionary, and then pass it to Notification observers through userInfo
field.
Finally, we can add a Notification observer at the base UIViewController
such that all UIViewController
s in the app can share the same logic. storageMetaData
and error
can be retrieved back from the userInfo
of the Notification object, see line 11–12.
App Lifecycle — Auto pause and resume
After discussing the UIViewController
lifecycle topic, let’s focus on the app lifecycle. What will happen when users send the app to the background during uploading files? Will the task be resumed automatically after the app is active in the foreground? The answer is “the SDK will take care of this, too!”
In iOS, there are three application states:
active
— the app is in the foregroundinactive
— the app is also in the foreground but cannot receive any events from the user. This is the case when you receive a call or an SMS, for example.background
— the app totally disappears from the screen
According to Apple’s documentation, each app can have around 30s to carry out its operations when it is sent to the background. The length of time can be shorter depending on the device situation. In other words, the Firebase SDK can still continue the uploading task at this 30s stage but it is forced to stop by the system after that. Any incomplete upload tasks will be resumed when the app becomes active again. See the above graph for a better illustration.
What about caching?
If you have used Cloud Firestore before, you were probably amazed by the local cache system. Even when the device is offline Firestore can save the user’s new data at the local database first and reupload them to the server automatically once connectivity resumes.
However, Cloud Storage for Firebase does not have a similar feature. Once the file cannot be uploaded due to a network issue, we have to upload it later again manually.
Summary
Cloud Storage for Firebase is a cloud tool for developers to store files and fetch them at the client-side with the help of a user-friendly SDK.
The SDK uses a singleton pattern to tackle the UIViewController
lifecycle issue. The uploading task can continue even when the UIViewController
is dismissed.
SDK has handled the app lifecycle issue for developers. It can resume the paused uploading task right after the app becomes active in the foreground.
However, SDK does not have a local cache system and users have to execute the uploading task manually.
Reference
- Introduction to Cloud Storage for Firebase
2. Pricing about Cloud Storage for Firebase and other great tools
3. Background tasks framework
4. UIImagePickerController introduction