PhotosPicker with Firebase Storage / SwiftUI

Sullivan De Carli
Swift Productions
Published in
4 min readJan 17, 2023

Learn how to pick up a picture from your phone library with SwiftUI PhotosPicker and upload the data to Firebase Storage.

Screenshot of iPhones with the SwiftUI and Firebase logo

Difficulty: Beginner | Easy | Normal | Challenging

Environment : Xcode 14, iOS 16 & SwiftUI

Full code at the end of the article

Create new Xcode Project

Open Xcode > App template > SwiftUI Life Cycle and call it PictureStorage

Firebase Set Up

To integrate Firebase to your project, I invite you to check out this article and get back if you don’t know how to configure a project with Firebase:

During the process, make sure to add the following dependency:

  • FirebaseStorage
Screenshot of Xcode with Swift package manager
Adding FirebaseStorage with Swift Package Manager

Set Up Firebase Storage

Unlike Firestore or Realtime Database, the Firebase Storage framework is built to store larges assets. It will be our server to store documents such as videos, images, audio files etc…

Let’s set it up in our console, go to Firebase console > Storage panel. Then, click on get started and select “start in test mode”, then select whatever storage location.

The setup of the Firebase console
Setting up Firebase Storage

Let’s code

Great! Now, we are ready to upload picture from our front-end to the Firebase backend. First let’s design the user interface to post pictures, import both frameworks at the top of the ContentView.swift file :

import PhotosUI
import FirebaseStorage

The PhotosUI framework will be useful to access the user photo library and FirebaseStorage to use their APIs to upload that selected picture.

Then, let’s observe these two State, add the following code over the body variable:

@State var data: Data?
@Statevar selectedItem: [PhotosPickerItem] = []

These reference will useful when selecting the picture and upload it as data. The PhotosPickerItem will be used to have a representation type of our data.

Let’s now create a form composed of a PhotosPicker with a button to upload to Firebase.

Copy/paste the code inside the body variable:

Great, we now have a button that let the user select one picture from his phone library. Following the selection, this image is displayed, if the user wish to change it, he can still click and select another one. Also, the button to publish is disabled if there are no images selected.

SwiftUI make it easy to manage the state of our user input in a few lines of code. You can run your application and test it out:

Screenshot of Xcode running with the Canva
Canva running in Xcode

Upload to Firebase Storage

It’s now time to implement a function to uplaod the data we selected to Firebase Storage. To achieve this, we first need to make a reference, copy/paste the following code after the two State we wrote earlier:

let storageReference = Storage.storage().reference().child(“\(UUID().uuidString)”)

This will be useful to generate a new identifier each time we are uploading an image to Firebase. Now, add the function below inside the button action:

  // Function to post data to Firebase Storage
storageReference.putData(data!, metadata: nil) { (metadata, error) in
guard let metadata = metadata else { return }
}

You can run the application, select a picture and you will see it on our Firebase console:

Screenshot of the Firebase Storage console with one image uploaded
Uploading a photo to Firebase Storage

You can upload as many images as you want, every time you upload one, it will get a new identifier.

Conclusion

In this tutorial, we connected our application to Firebase Storage, setup the framework and upload a photo in just a few lines of code using the new SwiftUI PhotosPicker to access the photo library of our phone.

You can support my work by either buying my book on SwiftUI & Firebase or subscribing to enjoy unlimited access to my articles and all of Medium through my referral link.

Full code:

import SwiftUI
import PhotosUI
import FirebaseStorage

struct ContentView: View {
@State var data: Data?
@State var selectedItem: [PhotosPickerItem] = []
let storageReference = Storage.storage().reference().child("\(UUID().uuidString)")

var body: some View {
Form {
Section {
PhotosPicker(selection: $selectedItem, maxSelectionCount: 1, selectionBehavior: .default, matching: .images, preferredItemEncoding: .automatic) {
if let data = data, let image = UIImage(data: data) {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame( maxHeight: 300)
} else {
Label("Select a picture", systemImage: "photo.on.rectangle.angled")
}
}.onChange(of: selectedItem) { newValue in
guard let item = selectedItem.first else {
return
}
item.loadTransferable(type: Data.self) { result in
switch result {
case .success(let data):
if let data = data {
self.data = data
}
case .failure(let failure):
print("Error: \(failure.localizedDescription)")
}
}
}
}
Section {
Button("Upload to Firebase Storage") {
// Function to post data to Firebase Storage
storageReference.putData(data!, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
return
}
}
}.disabled(data == nil)
}
}
}
}

--

--

Sullivan De Carli
Swift Productions

Consultant in iOS Dev at Deloitte. I write about Design & App development. Let’s have a chat at hello@sullivandecarli.com