Coding

Uploading Images | Vue.js + Vuetify + Firebase FULL PROJECT

  • 00:00:00 welcome back to this view of unify and
  • 00:00:03 firebase project the last video we made
  • 00:00:05 sure that only authenticated users can
  • 00:00:07 reach well this page here it is create a
  • 00:00:11 media page now I want to work on
  • 00:00:13 something on this page which isn't
  • 00:00:16 working in the way it should work the
  • 00:00:19 upload we only can paste the image URL
  • 00:00:22 thus far and that's nice but it would be
  • 00:00:25 nicer if we could pick one of our files
  • 00:00:27 and upload that file to the server so
  • 00:00:30 this is what we're going to work on in
  • 00:00:31 this video we'll add an upload button
  • 00:00:34 here and we'll make sure that we can
  • 00:00:36 upload a picked file to firebase
  • 00:00:41 so let's get started implementing this
  • 00:00:44 upload functionality and it starts in
  • 00:00:47 the create meetup the view fault in the
  • 00:00:49 template here where we have our image
  • 00:00:52 URL text field now as I just mentioned
  • 00:00:55 in the intro I don't want to enter a
  • 00:00:58 download URL into a text field anymore
  • 00:01:00 so we can basically get rid of that
  • 00:01:03 instead what we need is we need an input
  • 00:01:06 oops
  • 00:01:07 input op type file now if we change it
  • 00:01:11 like this and don't do anything else it
  • 00:01:13 looked like this and that's not super
  • 00:01:15 pretty now it turns out that your apply
  • 00:01:18 at least of the point of time I'm
  • 00:01:20 recording this doesn't have a component
  • 00:01:24 for this file upload so if we check out
  • 00:01:28 DD the inputs there we only get text
  • 00:01:31 fields we get no file input and if that
  • 00:01:34 changes feel free to use that until then
  • 00:01:36 I'll use a nice workaround though a
  • 00:01:38 button which will trigger this file
  • 00:01:40 upload window opening so what I'll do is
  • 00:01:44 I'll add another element here next to
  • 00:01:47 this input field and this field I'll add
  • 00:01:50 here is a V button element so this
  • 00:01:53 button ear should be a race button let's
  • 00:01:56 say and I'll give it a label of upload
  • 00:01:59 image now if we saved as we go back we
  • 00:02:02 see this upload image button here now
  • 00:02:05 obviously we can give it a class of
  • 00:02:07 primary to style it according to our
  • 00:02:10 primary style to make it red but the key
  • 00:02:13 thing is we now have this button here
  • 00:02:15 now if I click this button I want to
  • 00:02:18 trigger this input so that I can hide
  • 00:02:20 this input because it's ugly so there's
  • 00:02:23 a first step I'll hide the input here by
  • 00:02:26 assigning a style and setting the
  • 00:02:28 display to non-fans the Dom we can still
  • 00:02:32 work with it but of course we don't see
  • 00:02:34 it we can't click it directly that's why
  • 00:02:37 I have this button I'll add my click
  • 00:02:39 listener to this button and I'll say on
  • 00:02:42 click I want to pick a file so let's
  • 00:02:44 maybe execute a method called on pick
  • 00:02:46 file it doesn't exist yet I'll add it in
  • 00:02:49 a second so that's the file or that's
  • 00:02:52 the method I want to execute and then
  • 00:02:54 manhood I obviously wanna target this
  • 00:02:58 input here and simulate a click on it
  • 00:03:01 because it's hidden but I still want to
  • 00:03:02 interact with it
  • 00:03:03 now view chess gives us a nice feature
  • 00:03:05 so-called references we can assign a
  • 00:03:08 reference to any element in our Dom in
  • 00:03:12 our template here we do this by adding
  • 00:03:14 the ref attribute or directive to it so
  • 00:03:18 this is the directive we add wrapped and
  • 00:03:21 now here we can assign any key we want
  • 00:03:24 like for example file input again this
  • 00:03:27 string here is totally up to you though
  • 00:03:30 so with that assigned we can create this
  • 00:03:33 unpick file method by scrolling down to
  • 00:03:35 our methods and here I'll simply add it
  • 00:03:38 as a new method here and I want you
  • 00:03:42 trigger a click on this file input on
  • 00:03:46 this hidden file hidden file input so
  • 00:03:48 what I'll do is I will simply say this
  • 00:03:51 and now dollar sign ref gives us access
  • 00:03:54 to all the references in this template
  • 00:03:57 of this component so we can access our
  • 00:04:00 reference here by simply saying dot file
  • 00:04:04 input because that's the name we
  • 00:04:05 assigned and all I want to do is I want
  • 00:04:07 to execute a click there with click this
  • 00:04:10 is using this native Dom element click
  • 00:04:13 method we can execute
  • 00:04:14 – well simulate a user click on it with
  • 00:04:17 that this file input will now do its
  • 00:04:20 default behavior which is open a file
  • 00:04:22 picker and if we feel like it we can
  • 00:04:25 even go up to this file input where is
  • 00:04:28 it here and set the accept attribute
  • 00:04:34 here to image star to accept any image
  • 00:04:38 but nothing else we could also of course
  • 00:04:40 say image PNG delimited to PNG is only
  • 00:04:44 so there is the picker setup now let's
  • 00:04:47 see if it works we save this we get an
  • 00:04:50 error which error do we get here yeah
  • 00:04:54 often working too much with typescript
  • 00:04:56 I'm adding semicolons again we don't use
  • 00:04:59 semicolons in the style we use here
  • 00:05:01 right so back to our template if I now
  • 00:05:04 click this button we see this file
  • 00:05:06 picker open up and we can pick
  • 00:05:08 a file here now if I click open we don't
  • 00:05:11 see it here but it was indeed stored in
  • 00:05:13 this file input so that's one important
  • 00:05:16 step we're already closer to uploading
  • 00:05:18 this the next step is to make sure that
  • 00:05:22 whenever the attached file so the file
  • 00:05:24 attached to this input here does change
  • 00:05:27 that we actually get notice of that now
  • 00:05:31 for that well first of all structure is
  • 00:05:33 over multiple lines to make it easier to
  • 00:05:35 read but then I'll add a listener to the
  • 00:05:38 change event which is fired whenever the
  • 00:05:40 attached file changes I'll simply
  • 00:05:43 execute a method called on file picked
  • 00:05:46 so let's add this method here at the
  • 00:05:50 bottom on file picked here I'll get this
  • 00:05:55 default event passed into this method so
  • 00:05:57 the default Dom events is automatically
  • 00:05:59 passed into this method we don't have to
  • 00:06:01 do that explicitly and now we can
  • 00:06:04 retrieve the file from this event so on
  • 00:06:07 this event which is fired upon changing
  • 00:06:11 default input we actually can easily
  • 00:06:13 retrieve all the attached files by
  • 00:06:15 accessing event target which refers to
  • 00:06:18 that file input and then false so that's
  • 00:06:21 a list of false however we only will
  • 00:06:23 have one because it's not a multi-select
  • 00:06:24 input or anything like that so we can
  • 00:06:27 only select one file here in our
  • 00:06:28 application therefore we can retrieve
  • 00:06:32 the file by accessing the first element
  • 00:06:34 in this files array I'm more interested
  • 00:06:37 in the file name though for now so I'll
  • 00:06:40 create a new variable named file name
  • 00:06:42 wherever access files then the first
  • 00:06:45 element isn't set because we only have
  • 00:06:47 one element here in this array and it's
  • 00:06:48 the first one and then we can access
  • 00:06:50 file name on this fault that's a
  • 00:06:53 property provided by JavaScript by
  • 00:06:56 native vanilla JavaScript so now we get
  • 00:06:59 the file name as a next step I want to
  • 00:07:02 make sure that we actually do have a
  • 00:07:04 valid file with an extension basically
  • 00:07:08 so I can check if file name last index
  • 00:07:13 off
  • 00:07:16 if that is smaller or equal than a Syrah
  • 00:07:19 which means it doesn't have a dot in the
  • 00:07:21 filename which means it doesn't have an
  • 00:07:24 extension and even though that could
  • 00:07:25 theoretically be a valid image I don't
  • 00:07:27 want to upload that so here I will
  • 00:07:29 return an alert where I say please add a
  • 00:07:33 valid file and of course feel free to
  • 00:07:35 fine-tune this to your needs and be more
  • 00:07:38 helpful with your error message or
  • 00:07:40 whatever you like so we got a file and
  • 00:07:43 it's well well it at least with our
  • 00:07:45 basic validation here next I want to
  • 00:07:48 turn this file into a base64 string
  • 00:07:52 basically so you could say I want to
  • 00:07:54 turn this binary file into a string
  • 00:07:59 value which I can then later use to
  • 00:08:01 upload it so this can easily be done
  • 00:08:04 with the JavaScript file reader API for
  • 00:08:08 that I'll create a new constant file
  • 00:08:10 reader seems like a fitting name and I
  • 00:08:12 instantiate a new file reader again this
  • 00:08:15 is a vanilla JavaScript feature the file
  • 00:08:18 reader allows me to convert this file
  • 00:08:21 for this I have to call or I can call
  • 00:08:24 read data I read as data URL and I pass
  • 00:08:28 my file in there so the first element
  • 00:08:30 any files array however this will only
  • 00:08:34 trigger an event want to the stand it's
  • 00:08:37 an asynchronous action so I have to set
  • 00:08:39 up an event listener add event listener
  • 00:08:42 and I have to listen to the load event
  • 00:08:44 which is fired once it is done in the
  • 00:08:47 callback here I can now get access to
  • 00:08:49 the result of this operation which can
  • 00:08:51 take a couple of milliseconds up to
  • 00:08:53 seconds and here I want to set this
  • 00:08:56 image URL equal to file reader result
  • 00:09:03 and the interesting thing is the result
  • 00:09:07 here is this base64 value which is our
  • 00:09:10 image as text you could say now we use
  • 00:09:13 the image URL here on this image element
  • 00:09:16 in the source and the source is able to
  • 00:09:19 handle base64 strings so we will still
  • 00:09:22 get a preview with this approach which
  • 00:09:24 is why it shows it I want to make sure
  • 00:09:26 that you foul pick by the user can be
  • 00:09:28 pretty
  • 00:09:29 and that is easiest done by using such a
  • 00:09:32 base64 string now with that we store the
  • 00:09:36 result of this file reader operation in
  • 00:09:38 the image URL property which again we
  • 00:09:41 use the image element and our dom and
  • 00:09:44 with that we're pretty much done here
  • 00:09:48 one other thing I want to do is I want
  • 00:09:50 to store the raw file too and for that
  • 00:09:53 I'll add a new property which I'll just
  • 00:09:55 name image which is null initially and
  • 00:09:58 while I do have the text representation
  • 00:10:01 the base64 representation in the image
  • 00:10:03 URL in the image I want to store the raw
  • 00:10:06 file which is the file a later use once
  • 00:10:09 you submit the form so I will say this
  • 00:10:12 image equal false 0 so simply store the
  • 00:10:17 fall without any changes let's see if
  • 00:10:20 that works let's first of all compile
  • 00:10:22 this and let's now pick an image here
  • 00:10:24 like this one now that hasn't work we
  • 00:10:28 open the developer tools you see an
  • 00:10:30 error cannot read property last index of
  • 00:10:33 undefined the issue therefore is related
  • 00:10:36 to this line however it's really related
  • 00:10:40 to this line because I made a mistake
  • 00:10:42 here it's not file name it's just name
  • 00:10:44 so with that in place now it should work
  • 00:10:47 we now pick that image we see the
  • 00:10:51 preview here so that is working as
  • 00:10:53 intended and work that we can now
  • 00:10:55 continue filling this out and submit it
  • 00:10:57 but we still won't upload the fault
  • 00:10:59 because we haven't added any logic to do
  • 00:11:01 so so this is the next step we have to
  • 00:11:03 do make sure that upon submitting the
  • 00:11:06 form we actually store the file in
  • 00:11:08 firebase to upload that file once we are
  • 00:11:12 done we first of all have to change our
  • 00:11:15 uncreate meetup method in you create
  • 00:11:17 meetup component still there right now
  • 00:11:19 we submit the image URL and we store
  • 00:11:22 that in firebase and that was nice at
  • 00:11:24 the time we just pasted the image URL
  • 00:11:27 into this text field but with a real
  • 00:11:29 fault this won't work yes this would now
  • 00:11:32 hold this base64 string and yes
  • 00:11:35 theoretically we could store that in a
  • 00:11:36 database because if we then fetch it
  • 00:11:38 again it will work but it's not optimal
  • 00:11:41 because
  • 00:11:42 string is obviously a very big string
  • 00:11:44 and from our file size perspective it
  • 00:11:46 can get really big it's the whole image
  • 00:11:48 in a string in the end
  • 00:11:49 so therefore storing the image like this
  • 00:11:52 in that good we should store it at the
  • 00:11:54 database instead we should store the
  • 00:11:57 file as a binary file in the database so
  • 00:12:00 to achieve this what I'll do is I'll get
  • 00:12:02 rid of the image URL here and instead
  • 00:12:04 store image and refer to this image
  • 00:12:07 remember this image really is just the
  • 00:12:10 image which I set up here and we're then
  • 00:12:13 ultimately safe to fall here so this
  • 00:12:17 really is what I want to submit and what
  • 00:12:19 I want to store now of course you can
  • 00:12:22 even go ahead and add some validation
  • 00:12:24 here in oncreate meetup and make sure
  • 00:12:27 that the file is null so here we could
  • 00:12:29 check if this image or check the
  • 00:12:34 opposite to be precise if not this image
  • 00:12:37 simply return so submission will not be
  • 00:12:40 allowed if the image is still undefined
  • 00:12:42 or null as it is initially now with this
  • 00:12:45 basic validation in place let's move
  • 00:12:47 over to the more interesting place the
  • 00:12:49 create meetup action here in our view X
  • 00:12:53 store because this is where we pass this
  • 00:12:55 data to so let's head over to our store
  • 00:12:58 index.js file and let's work on that
  • 00:13:01 there we get this create meetup method
  • 00:13:04 and we store the image URL like this at
  • 00:13:06 the moment now of course we can simply
  • 00:13:09 remove that because in the first action
  • 00:13:13 here basically where we push our new
  • 00:13:15 meetup onto the array of meetups and
  • 00:13:17 firebase there we don't want to pass
  • 00:13:19 that download URL queue now what I want
  • 00:13:23 to do here is like a free step approach
  • 00:13:25 because we have like a egg chicken
  • 00:13:28 problem do you say that egg chicken we
  • 00:13:31 say that in Germany so whatever what we
  • 00:13:33 have here is we want to store an image
  • 00:13:36 on firebase and we want to make sure
  • 00:13:38 that it is connected to our meetup here
  • 00:13:43 so we need the idea of the meetup the ID
  • 00:13:45 of the meetup is created by firebase
  • 00:13:47 though so what I'll do is first of all
  • 00:13:50 I'll upload all the data I have to
  • 00:13:53 firebase to the database there which
  • 00:13:55 the idea the idea stand returns here
  • 00:13:58 there's keyword already retrieving I can
  • 00:14:01 then use this key to upload my image and
  • 00:14:04 associated with that Meetup
  • 00:14:07 then I'll get hopefully a success
  • 00:14:09 response and in this final step in the
  • 00:14:12 success response I actually get the URL
  • 00:14:14 to the image where it was stored by
  • 00:14:17 firebase then I reach out to the
  • 00:14:19 firebase database again and update my
  • 00:14:22 meetup there to add this download URL to
  • 00:14:26 the firebase object I have stored so to
  • 00:14:28 the meetup object I have stored on
  • 00:14:30 firebase I should say and then we're
  • 00:14:32 done so step one is already implemented
  • 00:14:34 we're storing this on firebase and let
  • 00:14:37 me quickly head over to firebase so
  • 00:14:40 here's our database and we already have
  • 00:14:44 to meet up here now I'll get rid of
  • 00:14:46 these for now because we'll replace all
  • 00:14:48 that anyways and let's head over to
  • 00:14:51 storage this is where I want to store in
  • 00:14:54 my meetups and this is basically the
  • 00:14:56 bucket where I want to put them now in
  • 00:14:59 the main dot J's fall where we set our
  • 00:15:01 project app there we have to add this
  • 00:15:05 storage bucket to the configuration so
  • 00:15:08 it's simply this URL here you just copy
  • 00:15:11 that including the GS colon slash slash
  • 00:15:14 at the beginning and enter it here this
  • 00:15:17 is important so that the firebase SDK is
  • 00:15:20 able to do that uploading for you with
  • 00:15:23 that let's head back and let's implement
  • 00:15:25 the actual uploading logic so as I said
  • 00:15:27 we already have the first step where we
  • 00:15:29 upload the meetups by pushing them onto
  • 00:15:32 this array and then we get this key now
  • 00:15:35 I won't commit my meetup at this point
  • 00:15:37 I'll comment this out for now instead of
  • 00:15:40 when I use this key to upload my image
  • 00:15:42 next so I will simply return the key
  • 00:15:45 here to keep it really easy to keep
  • 00:15:48 track of everything and I'll chain
  • 00:15:50 another then call here now and this then
  • 00:15:54 call here I'll get the key because I
  • 00:15:56 returned it in the previous than call
  • 00:15:58 here and here I now want to reach out to
  • 00:16:01 firebase storage first of all I'll
  • 00:16:04 determine the file name and I can get
  • 00:16:07 that from my
  • 00:16:09 payload and they're from the image the
  • 00:16:12 name remember payload has an image
  • 00:16:15 because we pass image as part of this
  • 00:16:19 object here so image is part of the
  • 00:16:22 payload which reaches this action here
  • 00:16:25 so we're retrieving the name of that
  • 00:16:27 image additionally I want to know which
  • 00:16:30 extension has so I can receive retrieve
  • 00:16:33 the extension and store it by simply
  • 00:16:35 taking the filename and slicing it and I
  • 00:16:40 want to slice it at the position of the
  • 00:16:42 last index of a dot so this will
  • 00:16:46 basically give me the slice after the
  • 00:16:48 dot which should be the extension and
  • 00:16:51 with Dad we got the extension now I want
  • 00:16:55 to store it in firebase so for that we
  • 00:16:59 already import firebase here for that
  • 00:17:01 I'll reach out to firebase firebase but
  • 00:17:05 not the database but to the storage part
  • 00:17:08 of it instead just like with off and
  • 00:17:10 with database we get access to the
  • 00:17:13 storage related methods by executing
  • 00:17:15 storage as a method on the firebase
  • 00:17:17 object and then there just like on the
  • 00:17:20 database you get a reference to the path
  • 00:17:22 where you want to store it and here
  • 00:17:24 meet-ups makes sense however I don't
  • 00:17:27 just want to store it on meetups I want
  • 00:17:30 to store it on meetups and then connect
  • 00:17:33 it to the key we have here
  • 00:17:35 so this basically will be the file name
  • 00:17:38 we save it at so I want to store it me
  • 00:17:40 at meetups and then slash plus key plus
  • 00:17:45 a dot plus the extension so what this
  • 00:17:49 will do is it will store it in a meetup
  • 00:17:51 subfolder because of the slash so that's
  • 00:17:53 a folder and then the file name will be
  • 00:17:56 the key
  • 00:17:57 so does random ID generated by firebase
  • 00:17:59 dot the extension of the file so that we
  • 00:18:02 keep that extension on the fall we store
  • 00:18:04 and that is actually as novel return
  • 00:18:07 this because it will return a promise so
  • 00:18:09 that we can chain another then call now
  • 00:18:12 here I will get some image information
  • 00:18:16 I'll call it like this or generally
  • 00:18:18 maybe file data so the data about this
  • 00:18:22 file upload
  • 00:18:23 was successful which it hopefully was
  • 00:18:25 the important thing I can retrieve here
  • 00:18:28 is the image URL which I want to use now
  • 00:18:31 I want to use the image URL to reach out
  • 00:18:35 to to firebase and update the on the EDD
  • 00:18:40 image their device URL there now to do
  • 00:18:43 there's an easy way and because all you
  • 00:18:45 need the image URL in a number then
  • 00:18:48 block there after I'll quickly create a
  • 00:18:50 variable before I start this whole
  • 00:18:52 promise chain and I'll name it image URL
  • 00:18:55 I'll also create one for the key and I
  • 00:18:58 will therefore store the key in that key
  • 00:19:00 variable here and I'll store the image
  • 00:19:03 URL here in this image URL variable by
  • 00:19:06 accessing file data and then there we
  • 00:19:10 can get access to meta data and then
  • 00:19:16 download URL source download URLs now
  • 00:19:21 these could be multiple as URLs if we
  • 00:19:22 had uploaded multiple files we only
  • 00:19:24 uploaded one so it's basically the first
  • 00:19:27 element in this array this is the URL
  • 00:19:29 pointing to our fall and it is the URL
  • 00:19:32 we can paste into the browser to load
  • 00:19:34 our image so storing this now I want to
  • 00:19:37 return a number fire-based call this
  • 00:19:39 time to the database again because as I
  • 00:19:43 said now I want to update update my
  • 00:19:45 element in the database with this
  • 00:19:48 download URL because I still want to
  • 00:19:50 store that in the database so I'll reach
  • 00:19:52 out to my database and there rep queue
  • 00:19:56 meetups because that is where I stored
  • 00:19:59 my meetups right however now I need to
  • 00:20:01 access my specific meetup which I can do
  • 00:20:05 with child and then the key that is why
  • 00:20:09 I stored it in a variable here because I
  • 00:20:11 needed in this then block to key was
  • 00:20:15 created by firebase and it is the
  • 00:20:17 identifier of the element which was
  • 00:20:19 created in the first step of this
  • 00:20:21 promise chain in this step here so now I
  • 00:20:24 get access to that and we can now
  • 00:20:27 conveniently call the update method to
  • 00:20:29 update this which means it won't remove
  • 00:20:32 it it won't override it it will only
  • 00:20:34 overwrite the fields we specify
  • 00:20:36 we specified them in a javascript object
  • 00:20:38 and here I specify the image URL field
  • 00:20:41 and if that feels doesn't exist yet as
  • 00:20:44 it is the case here it will simply
  • 00:20:46 create it
  • 00:20:47 so here image URL should have a value of
  • 00:20:50 image URL so the image URL we fetch them
  • 00:20:54 saved in this variable now with that
  • 00:20:57 let's add another than block here here
  • 00:21:01 we would get back some data but I'm not
  • 00:21:03 interested in that instead what I want
  • 00:21:05 to do here is I want to commit this to
  • 00:21:07 my local store because thus far I can
  • 00:21:10 remove it up there that's far we only
  • 00:21:12 worked in firebase we are stored data we
  • 00:21:15 uploaded the file but we haven't
  • 00:21:17 reflected any of these changes in our
  • 00:21:19 local store which I of course want to do
  • 00:21:21 so here it's time to commit create meet
  • 00:21:24 up again I want to take my old meetup
  • 00:21:27 data which I already have so that is
  • 00:21:30 just the same code we we used before so
  • 00:21:33 use this meetup here
  • 00:21:34 however this meetup lacks the image URL
  • 00:21:37 so I will add it here I will add image
  • 00:21:40 URL image URL and we of course need this
  • 00:21:43 because we're retrieving it in our
  • 00:21:45 template we need dead image URL and this
  • 00:21:47 will be the image URL we got from
  • 00:21:49 firebase from firebase because we're
  • 00:21:52 referring to that image URL variable
  • 00:21:55 which I'm setting here whoo so that was
  • 00:21:59 a lot so with that it's set we're now
  • 00:22:01 having this hopefully stored of firebase
  • 00:22:04 and now let's simply try out if it works
  • 00:22:07 if we head over and we organize a new
  • 00:22:11 meetup we already are logged in still so
  • 00:22:14 let's create a new meetup de San
  • 00:22:16 Francisco meter because the images from
  • 00:22:19 San Francisco so the location ship roll
  • 00:22:21 be their cue let's pick that image it
  • 00:22:25 will be awesome and I won't bother
  • 00:22:29 changing this year I'm interested in if
  • 00:22:32 that works too let me open the console
  • 00:22:33 to see any potential errors click create
  • 00:22:36 meetup and we get an error cannot read
  • 00:22:39 property download URLs of undefined
  • 00:22:41 now let's check our firebase back-end
  • 00:22:44 the meetup was created here we don't see
  • 00:22:46 the download URL because they clearly
  • 00:22:48 failed and
  • 00:22:49 storage we also see no fall there so the
  • 00:22:54 file upload itself seemed to fail that's
  • 00:22:56 why we don't have any download URLs
  • 00:22:58 probably now let's investigate why that
  • 00:23:01 happens so after a short investigation I
  • 00:23:04 made a nice discovery and it's super
  • 00:23:09 hard to spot but there is one thing I
  • 00:23:13 forgot when setting up this code do you
  • 00:23:15 spot it well it never hurts to actually
  • 00:23:20 also send the file to the backend right
  • 00:23:23 I got my reference here when I reach out
  • 00:23:26 to storage and I basically set up where
  • 00:23:29 to store the file and how it should be
  • 00:23:31 named but it would probably also be
  • 00:23:33 beneficial if I would specify the follow
  • 00:23:36 on a store and we do this by storia by
  • 00:23:39 chaining put so just like on the
  • 00:23:41 database where we also set up a pop and
  • 00:23:43 then we call update or push well for
  • 00:23:45 files we use put and that always is a
  • 00:23:48 good idea to use if you want to get this
  • 00:23:50 file on the server so for today isn't
  • 00:23:54 there of course we now simply pass the
  • 00:23:56 payload image which is this raw image
  • 00:23:59 file keep that in mind so with that
  • 00:24:01 crucial change in place let's go back
  • 00:24:04 and I'll quickly get rid of my entry
  • 00:24:09 here in the database first don't want to
  • 00:24:11 have that so let's reload that should
  • 00:24:13 should be gone it is so let's organize
  • 00:24:16 the number Meetup let's see if it now
  • 00:24:17 works so the san francisco meetup in san
  • 00:24:20 francisco where we upload these san
  • 00:24:23 francisco image and i've awesome here
  • 00:24:27 let's hit create meetup now we don't see
  • 00:24:32 it here now it's there now the image
  • 00:24:34 loads that seems to work and obviously
  • 00:24:37 we saw it work but if we check out
  • 00:24:38 firebase here we see the image URL and
  • 00:24:40 unrestored we also see that we have this
  • 00:24:44 meetups folder where we have this file
  • 00:24:47 in there keeping the file extension and
  • 00:24:49 having this cryptic name which is the ID
  • 00:24:52 we got in the firebase database so with
  • 00:24:56 that this is working and obviously if we
  • 00:24:58 click on it we also see the image here
  • 00:25:00 so now firebase upload a
  • 00:25:03 is working here we are now able to
  • 00:25:06 upload images and not just pick URLs
  • 00:25:08 when creating new meetups and I say this
  • 00:25:10 is a huge step forward now in the next
  • 00:25:13 videos I want to dive deeper into how we
  • 00:25:17 can actually change existing meetups so
  • 00:25:20 add some edit functionality and of
  • 00:25:22 course finally implement a registration
  • 00:25:25 functionality so we're nearing the end
  • 00:25:27 of the series but we're not there yet
  • 00:25:29 see you on the other videos bye