The Upload Functionality



The course is part of this learning path

Start course
2h 13m

In this course, we're going to create a Snapchat clone using structs and various advanced techniques of Firestore.


Hi. Within this lecture, we're going to take care of our upload functionality. First of all, we're going to do it in a basic way so that we will display the uploaded image in the Feed View Controller, okay? But later on we're going to change our algorithm so that we can display all the pictures grouped in one post so that every snap owner has only one post so that we can consolidate all the snaps and display them in an image slider within another View Controller, okay? So, first of all, we're going to do the basic way. However, we're going to upload our images to the storage eventually. So, first, we're going to write that function and you know how this goes. We're going to create a storage instance and that we're going to upload everything to the storage and get the respective Url so that we can work on that Url, okay? So, in fact, we can start to create our storage reference so this will drive from storage and we have to import the Firebase in order to do that, okay? So, let me import the Firebase and then come down here then I can call the So, this is my storage instance and remember I have to create a storage reference, right? So, this will be storage.reference. Now, using that reference I can specify the folder that I'm working in. So, this will be storageReference.child. Remember, we have to give a name over here to specify the folder name. So, we will be saving our pictures inside of a folder called media, okay? So, you can choose this name. You can call it images, you can call it media, you can call it storage, whatever you want but you have to have a folder in order to be more structural, okay? Later on I'm going to create my data, remember we have to convert our image to a data in order to upload it. And this will be jpegData and the compression quality I'm going to go with 0.5. So, I'm going to use this data to save in my media folder. So, how do we do it? We're going to do it exactly like we did in the Instagram clone section. First of all, we have to give it a name and this name will be coming from UUID. Remember, when we say uuidString, so let me delete this and you can see it better, it will give us a made up string like that and we're going to use it as a name for our images so that we will have a unique name every time we upload an image. So, I'm going to call this imageReference and this will be again derived from mediaFolder, okay? MediaFolder.child and the name will be the uuidjpeg. So, we have to go like this uuid and we have to specify of course this quotation marks and say jpeg so that it won't be uploaded as a weird file, it will be uploaded as a jpeg file. Later on, you can just say imageReference.putData and it will ask you for a data and a metadata and in return it will give you a completion block, okay? So, we want, we don't want that but we want this, upload data, metadata, and the completion block. So, data will be data, I don't need any metadata to upload to the server but in completion, I'm going to get a metadata and an error. So, of course, I'm going to start to check if error != nil and if error != nil I'm just going to display an error message to the user. So, I believe we don't have this makeAlert function, so I'm going to copy it from other View Controllers and paste it over here so that I can call self.makeAlert and call this error and the message will be error.localizedDescription and if this is nil then I'm going to call something like Error, okay? And else, and else I'm going to take the imageUrl. So, remember you have to say imageReference.downloadURL, so this will give you either a Url or an error. And this time you can just go for if error == nil and go for the Url over here. So, let me close this down so we can see it better. In this case, I'm just going to create my imageUrl and it will be something like url.absoluteString. This is not absoluteUrl, absoluteString, okay? So, later on, in fact, we're going to save this imageUrl along with the other parameters that we want to the Firestore. So, first, I'm going to create my Firestore instance. So, this will be Firestore.firestore then I can come over here and decide where to save it. Something like fireStore.collection and I'm going to call the Snaps. Again, I'm going to add a document. It will ask me for a dictionary and a completion block. It will give me a completion block, actually. So, you can choose this one and you can create your snapDictionary over here. So, what will be in our snapDictionary? First, we have to specify the imageUrl and the username of the user and along with those, I'm going to go for a date as well so that we can delete when 24 hours is passed. So, let's go for imageUrl and imageUrl. So, I'm force unwrapping this, so if you want you can use e flat in order to be more secure, okay? And I'm going to call my username snapOwner, okay? So, this will be the snapOwner. Remember, we can get the username from userSingleton.sharedUserInfo.username. So, that's how we use singletons. And over here, I'm going to specify the date as well. Again, in order to order everything by date or in order to just delete them after 24 hours, so remember how we got date in Instagram clone fieldvalue.servertimestamp. So, I'm going to cast this a string to any dictionary so that I can come over here and say snapDictionary. And if I hit 'Enter' over here it will give me an error. So, you can check to see if error != nil or if error == nil. So, if error != nil, it's your call to display an error message to the user, I'm going to do it, and let's say double question mark error. And if that's the case, then what we want to go to, what we want is to go to Feed View Controller and reset this view but just let me test this to see if it's working or not. We're going to need two images anyway, so let me upload the first one. So, I'm going to say upload and I won't know if this is uploaded or not because I didn't specify like going to Feed View Controller or something. So, let me do it anyway, we're going to do it eventually. So, I'm going to say self., remember we're working with a Tab Bar Controller over here so I can just say tabBarController.selectedIndex = 0. It's going to take us to the Feed View Controller. And, of course, I'm going to change the upload image view image as well to its original image which is our select image. So, let's say selectimage. So, let's see if this was selectimage or select? It's selectimage. So, you can come over here and say selectimage.png and let me run it one more time. We're going to need two images anyway because I'm going to show you something. So, let me open this, okay? And let me come over to my upload and upload another picture over here. So, let's choose this and say 'upload'. Once we hit that it will get uploaded to the server and it will take us to the Feed View Controller. So, let's go back to our Firestore. So, if I refresh this then we're going to see the snaps, right? So, let's see. Here you go now we have the snaps collection and as you can see we have two documents over here. So, we have the snapOwner of James Hetfield and we have the imageUrl and everything. So far, this is working good, but in fact we don't want that, right? What we want is to have one single document. So, if you can just paste your Url to your browser, you will see that this is in fact working, okay? And I have no objection to that. But I don't want two documents for only one snapOwner because remember our prototype when we have seen the Snapchat clone in the first lecture of this section, we have consolidated every snap of one user to one post. That means we have to get every step inside of only one document. So, how can we do that? I will show you a way to do that, but it's only my way you can come up with a better one later on, actually, but you will see how to work with a raise inside of a collection, inside of a document as well, right? So, let's stop here. Within the next lecture, we're going to do that and we're going to see the advanced usages of Firestore and then we will complete our app by retrieving all data to show them in feed.


About the Author
Learning Paths

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.

Covered Topics