In this course, we're going to create an Instagram Clone and learn how to work with cloud servers using Firebase. By the end of this course, you will be well-equipped to build your own apps!
This course is designed for anyone who wants to:
- Learn about iOS development and coding
- Move into a career as an iOS developer
- Master Swift skills
To get the most out of this course, you should have some basic knowledge of iOS.
Hi. Within this lecture, we're going to learn how to upload the chosen image from the UploadViewController to the storage of the Firebase. So far, we have created this user interface so that we can go to the gallery and get the image back. And we have to upload it to the storage and then to the database as well so that we can retrieve those data and show them to the user. And remember, we use storage to store the media like image, like videos and we use database to store the data like the command or who uploaded this picture or the URL of the stored image. And we're going to learn how to do that so that we can get those back and display them into the feed of the user, okay?
The first thing to learn is actually how to upload the image to this storage so that we can get the uploaded URL and save it to the database. And again, like we did in the authentication, we have to initialize this storage as well. And we're going to do that in the database. And we're doing this only for once. Remember, we have to initialize this, after that we can use it as we want. We're going to set up some security rules in the database and storage as well. At the end of this section we're going to take a deeper look at in the security rules as well. But for right now we're going to start as in the default mode so that we can write and read data from the storage.
So, if you click on this, 'Get Started' button you will see the security rules of the Cloud Storage. So, what we have here is defining who can read and who can write to the storage. And as you can see, it says that we allow the read and write if only and only if the request is authenticated, okay? So, if a user gets authentication as in they can sign up and sign in so then after they can actually upload data or download data from the search. And in fact, that's what we want to make our app more secure and we're going to implement this in our database as well, at the end of this course, but this is a default behavior for our storage as usual.
So, that's what I want. I want people to access my storage as long as they are authenticated. So I'm going to hit 'Next' and next thing it will ask me for to choose a location for my Cloud Storage. And here you can see we have Europe, US, Asia, North America and other locations. So, it really doesn't matter which you choose. You can just access your data in any location you want. But if you're focusing on the US market for example, you can choose one of the US market locations or if you're focusing on Europe in your app, if you're targeting Europe users, you have to choose Europe in order to make your storage, in order to make your database act faster and by the way it won't affect too much. Maybe, you're going to do queries in one second if you don't pay attention to this location, but if you pay attention maybe it's going to be less than one second. But eventually, I believe, you have to choose your location with careful decisions because you cannot change this after you choose, okay?
Wherever you choose, it will be stated as your main location for your storage and for your database as well. So, if you're targeting all the world, then just choose one of the locations like Europe or US. And if you're focusing on specific location like Asia, or US, or Europe. Then choose the related one and then hit 'Next' and it will create your storage for you. And this location will be used as a default location when we initialize database as well. So, they will be synchronized. And here we go, we have our storage created. So far, we don't have anything in our storage as you can see. We can manually add some folders from here, like if you click on this '+' button, you can call this media or you can call this images, videos, whatever you want.
You may not choose to create any folder like this at all, but I'm going to create a media folder and I'm going to store our images inside of this media folder in order to be more structured but it's not mandatory, okay? And it's not mandatory to do this from here. I'm going to write a code for this later on. And it's not mandatory to initialize this from this dashboard. If you have created your storage, if you have chosen your location, then it's okay.
So, let's come back to our documentation. And lets go for iOS as usual. And in here, we have great documentation regarding the storage. If you come over here to get started, you can see the necessary pods. We have actually done this before. We have added the pods and as you can see, we have some sample codes regarding how to upload a file, how to download a file. And don't worry, I'm going to show all of this in the course but I really suggest you go back here and just read those documentation if you have time because Firebase has so many modules, so many methods, so many functions, we cannot go over them one by one, but I'm just showing you the most used ones, the most used operations but there are some details that may come in handy when you're developing an app with Firebase. So, I suggest you take a look around here.
So as you can see we have an example here, we're creating a reference from Storage.storage and we are selecting a child and name for our folders and we're creating some other references to upload and download images. We're going to do that. Don't worry. But I believe the documentation of the Firebase is great. So, when a user clicks on this 'Upload' button, we have to upload the image to the Storage first. So, let me grab Firebase library from here. And then we can create the storage reference that has been mentioned in the documentation as well.
So, I'm going to call this storage and this will drive from the storage class of the Firebase, okay? This... the capitalized as storage and as you can see this is a service that supports uploading and downloading objects. So, this is exactly what we did in the art. So, Storage.storage, okay? So, this will create a storage instance, an instance of the storage class. And we're going to use that storage instance to create references and upload images.
So, next thing would be to create our storage reference, okay? And you can do that in one line as well. I'm doing it on purpose so that you can understand the steps more clearly. So, we're creating a storage instance and then we are creating a reference from that instance so that we can use that reference to upload our image. So, that's what we're going to do in the database as well. We're going to create a Firestore instance and then a reference. And let me create our media folder. So, that's the folder that I'm creating right now.
So, if I say, storage Reference. child, okay? So, whenever you see .child in at Firebase, it means that we have to go one level below. So, if I had another folder inside of that media folder and then I can say .child media .child something else. And now I'm inside the reference and I'm saying .child to go one level below to media folder, okay? So, it will refer to my media folder if I say .child media. So again, if I had another thing in here, like images, it will just create the images folder for me. You don't have to manually go and create that media folder. But I'm going to go for the name media. And again, if you put another thing in here like .child media two, it will create another example, another folder inside of your media folder, okay? But I'm not going to do that because I only need one folder to save my images.
So, let's upload our image, right? In order to upload our image, we have to convert it into a data. Remember what we did in the art book. We just don't save images as a UI image to a server or a database. We have to create the images to a data type so that we can get them and upload them. After downloading them, we can also convert them back to the UI image and we know how to do that. So, that's exactly what we're going to do in here as well in order to get our chosen image and compress it and change it to a JPEG data and just save it to the database or storage. So, remember how we do that: if let data = imageView.image.jpegData And it asks us for a compressionQuality. We have gone with 0.5 I believe, and that was okay. So, I'm going to go for 0.5 again. So, maybe you can try something like 0.3, 0.4 to just work with some lower resolutions as well. And in here we're going to say let media reference. Okay, I'm creating a reference for my image right now, not my media folder, and it's going to be driving from the mediaFolder.child. So, whatever I give us a name here like image.jpeg, it will save my image like this. Okay, it will just rename my image like image.jpeg and it'll save it to this storage. And I believe this media reference is not a good name because we are creating a reference not for our a media folder, we are creating this reference for our media image, okay? So, we are creating this for image reference. So, I believe we should rename this. So, let me call this image reference rather than media reference, okay, so that you can understand it better. And then I'm going to say imageReference.putData, okay?
It will ask me for a data to put on the storage and we have that data, right? And we want with the completion block, because we want to check if we have any error, if we manage to upload the folder, manage to upload the file to the folder so that we can get back in the metadata that we want. So, data is data, metadata is kind of a description that we want to send with the image and we don't need one in here, okay? So, I'm going to go for nil, and completion is a regular completion callback function. If you hit 'Enter', it will give us a main metadata and we're going to need that. So, I'm going to name this metadata. And for error, we're going to say error. So, as usual, I'm going to start by checking if error is not nil. And if error is not nil, you can just show an alert message to the user. I'm just going to go for a print error.localizedDescription. And in the else, of course, we want to do something, right? We want to get the URL of the uploaded image. Why do we even need that? Because we're going to save this URL to the database along with the other information like command and who posted, post owner, and date. So, every image, every post in the database will have an image URL, a command, and other features as well. And previously, we had this by saying metadata.imageURL. But right now as you can see, this doesn't give us the image URL. In order to get the image URL, now we have to do something like imageReference.downloadURL. But only after you complete putting data you do this. So, after you are done in here then in the else block if there is not any error, you can just call imageReference.downloadURL. And in this, I'm going to call this URL and I'm going to call this error. And this time I'm going to check if error is actually nil, okay? I'm not going to show any alert messages in here. If the error is nil, then I'm going to go for the URL So, I can just call this imageURL, let imageURL is going to be URL.absoluteString. Look, there is an absoluteURL as well. We are looking for absolute string, so pay attention here. This is string 1. So, I'm going to print this string, okay? I'm going to print this imageURL to see if we really managed to upload the image to the storage. So, now we can test this actually. Let's run this in our simulator. And remember our simulator has some prebuilt-in images in the photo gallery. But I really suggest you go and find some images on your own because these images are too big and it will work, it will get uploaded, but I believe it's more realistic to work with an image like this. So, as a command, it actually doesn't matter if I write a command here or not because we are not doing anything with a command right now, we are just uploading this image to the storage. So, whatever you write here won't get attention by the Xcode, so just write something or just leave it empty. All we have to do is just hit the 'Upload' button to see if we can manage to send this to the storage. And once I hit the 'Upload' button, as you can see, in the logs, I get this URL, I get this optional URL because this is optional right now, as you can see, and we're going to take care of this later on. But for right now, we have to take this URL and we can see if we really managed to upload our image to this URL. So, let me copy this. Let me open Safari or any other browser and paste this in to see if we get the image. Yes, it asks for a download permission if I allowed that. Here we go, we see the image as we have uploaded. So, now I managed to upload my image to the Firebase storage. And in fact, let's go back to our media folder in here. Right now we're going to see our image renamed as image.jpg. And in here, as you can see we have the file location, the URL here and we don't have any metadata because remember we actually chose this to be nil. And if you want to save any description in here, you can do that, but we don't need that right now. So far so good. In fact, we're not done with the whole uploading process. We're going to encounter some issues because of the name of this image, but we're going to take care of that one in the next lecture.
Atil is an instructor at Bogazici University, where he graduated back in 2010. He is also co-founder of Academy Club, which provides training, and Pera Games, which operates in the mobile gaming industry.