Coding

Firebase Cloud Functions – Resizing Images after Upload

  • 00:00:02 welcome to this video great to have you
  • 00:00:04 on board in the last video of this
  • 00:00:06 series I explained what firebase cloud
  • 00:00:08 functions are about in this video I want
  • 00:00:11 to get started with writing a firebase
  • 00:00:12 cloud function and we will write a
  • 00:00:14 function that takes an image we put into
  • 00:00:18 the cloud storage that automatically
  • 00:00:21 runs whenever we put an image there I
  • 00:00:22 should say and that then simply resizes
  • 00:00:26 the image into different format let's
  • 00:00:29 have a look at how this works in this
  • 00:00:30 video
  • 00:00:34 so here I am in the firebase console I'm
  • 00:00:37 creating a new project here so let me
  • 00:00:38 quickly do that and in that project I
  • 00:00:41 want to add this firebase cloud function
  • 00:00:44 that will run whenever a file is
  • 00:00:46 uploaded so with that let's wait for
  • 00:00:49 this to finish
  • 00:00:52 whence a dead finish you can go to
  • 00:00:54 functions but here at least at the point
  • 00:00:57 of time I'm recording this you can't
  • 00:00:59 write your function we have to do that
  • 00:01:01 locally with the help of firebase CLI
  • 00:01:05 it's super simple to do though so let's
  • 00:01:07 quickly install that Here I am in the
  • 00:01:11 terminal of the Mac or open the command
  • 00:01:13 prompt on Windows and then we need to
  • 00:01:15 install a global package through NPM for
  • 00:01:18 that you need to have NPM nodes package
  • 00:01:21 manager installed which you do install
  • 00:01:23 by going to note J s doric and simply
  • 00:01:26 installing the latest version of node J
  • 00:01:29 s with that installed you can run NPM
  • 00:01:32 install – G firebase – tools this is the
  • 00:01:37 tool set DC live firebase offers now on
  • 00:01:40 Mac and Linux you might need to add a
  • 00:01:42 sudo in front of this to get the right
  • 00:01:44 permissions thereafter you might also be
  • 00:01:46 prompted to enter your password and once
  • 00:01:49 you did that it will install this
  • 00:01:50 firebase toolset which you can use to
  • 00:01:52 well run your firebase projects or
  • 00:01:55 actually create a firebase project
  • 00:01:57 create a environment where you can write
  • 00:02:00 firebase cloud functions so I'll be back
  • 00:02:02 once this installation finished once it
  • 00:02:05 finished you first of all have to sign
  • 00:02:08 into your firebase account for that you
  • 00:02:10 can simply type firebase this command
  • 00:02:14 should now be available since you
  • 00:02:15 installed the firebase tools global
  • 00:02:17 globally login once you type this you
  • 00:02:20 are asked whether you want to allow the
  • 00:02:22 collection of data and thereafter a new
  • 00:02:25 tab should open where you have to
  • 00:02:27 authenticate now you will have to copy
  • 00:02:30 that URL it shows you there and simply
  • 00:02:32 log in to your firebase account in that
  • 00:02:35 new tab that opened once you get off
  • 00:02:40 that it should successfully complete
  • 00:02:42 here in the terminal and thereafter you
  • 00:02:45 can create a new firebase project with
  • 00:02:47 the CLI for that I'll first of all
  • 00:02:49 create a new folder I navigated into
  • 00:02:52 that new folder and in there the folder
  • 00:02:55 which you want to turn into your
  • 00:02:57 firebase project and as a side note this
  • 00:02:59 could be your angular view or a react
  • 00:03:02 project where you want to add some
  • 00:03:04 firebase functionality so this can also
  • 00:03:06 be a folder where you have another
  • 00:03:07 project already but in this folder which
  • 00:03:10 is an empty folder I'll run firebase in
  • 00:03:13 it and this will now initialize this as
  • 00:03:15 a firebase project now you're then asked
  • 00:03:18 which features you want to use in this
  • 00:03:20 project and I want to use functions so
  • 00:03:23 I'll navigate there in the command line
  • 00:03:24 and hit space to enable this you could
  • 00:03:27 also turn on hosting if you want to use
  • 00:03:30 firebase hosting for your single page
  • 00:03:31 application let's say but I won't do
  • 00:03:33 that here so I want you just have my
  • 00:03:36 functions here with that I'll hit enter
  • 00:03:40 and then you have to choose one of your
  • 00:03:44 project so I'll choose the project I
  • 00:03:45 just created in the firebase console can
  • 00:03:48 then choose the language you want to use
  • 00:03:50 your cloud functions you could use
  • 00:03:51 Chavez at typescript but I'll stick to
  • 00:03:53 JavaScript and with that you're almost
  • 00:03:56 done you can then opt to automatically
  • 00:03:58 install or require that we could require
  • 00:04:00 dependencies and I want to do that here
  • 00:04:02 so let's wait for this to finish
  • 00:04:03 thereafter can write our function code
  • 00:04:06 these set about the project finished and
  • 00:04:09 I opened it in Visual Studio code it's
  • 00:04:11 your normal web project editor which
  • 00:04:13 ever editor you use there you'll find a
  • 00:04:16 configuration file which holds the ID of
  • 00:04:18 your project this of course should be
  • 00:04:20 well your project ID firebase Jason
  • 00:04:23 doesn't hold any configuration and then
  • 00:04:25 we got this functions folder there we
  • 00:04:27 also get a node modules and a
  • 00:04:29 package.json fault these are now the
  • 00:04:31 dependencies of the function we're
  • 00:04:33 writing and in the index.js file here we
  • 00:04:36 can write our function our firebase
  • 00:04:39 function here this commented out part if
  • 00:04:42 we commented in actually already is a
  • 00:04:45 firebase cloud function this would be
  • 00:04:47 one that listens to incoming HTTP
  • 00:04:49 requests you remember that slide I
  • 00:04:52 showed you in the last video
  • 00:04:53 that would be the case or this would be
  • 00:04:55 an example for how you can create your
  • 00:04:57 own HTTP endpoint now I'm not interested
  • 00:05:01 in creating my own HTTP endpoint here I
  • 00:05:04 want to create a function that reacts to
  • 00:05:08 files being uploaded or file events in
  • 00:05:11 general in my cloud storage so let's see
  • 00:05:15 how we can write such a function do you
  • 00:05:17 react to storage events I actually won't
  • 00:05:20 use the HTTP area on my functions
  • 00:05:25 package here which is coming from
  • 00:05:26 firebase functions which is made
  • 00:05:28 available by default but instead here I
  • 00:05:31 want to use the storage area
  • 00:05:33 now on storage we got the object or
  • 00:05:37 bucket property or method to be precise
  • 00:05:42 this simply means do you want to specify
  • 00:05:44 a specific bucket for which you want to
  • 00:05:46 listen to events or if you directly
  • 00:05:49 specify object and execute this as a
  • 00:05:51 method without passing any arguments
  • 00:05:53 then you will say I want to use the
  • 00:05:55 default bucket the default bucket your
  • 00:05:57 firebase Project chips well I will use
  • 00:05:59 that bucket there you then have one
  • 00:06:02 method on change and this now is exactly
  • 00:06:05 doing what it sounds like it will give
  • 00:06:09 you the information or it will trigger
  • 00:06:11 whenever something changes on change
  • 00:06:14 therefore requires a function you pass
  • 00:06:17 as an argument and this function will
  • 00:06:19 get some event data so this argument
  • 00:06:22 will be passed into the function
  • 00:06:23 automatically by firebase and then in
  • 00:06:26 there we don't send a response because
  • 00:06:28 we're not creating a HTTP endpoint in
  • 00:06:30 there instead in the end we will return
  • 00:06:34 to tell firebase that we're done if
  • 00:06:37 you're writing some async code in there
  • 00:06:39 which we eventually will you should
  • 00:06:41 return a promise by the way but I'll see
  • 00:06:43 all of that for now let's simply return
  • 00:06:46 here and besides returning or before
  • 00:06:49 returning i want to simply console.log
  • 00:06:52 my event object to see what's inside of
  • 00:06:55 it and with that we got our first basic
  • 00:06:58 function created as a side note if you
  • 00:07:00 want to have multiple functions you
  • 00:07:01 would simply export another function
  • 00:07:05 here which you also set up in the same
  • 00:07:07 and that would then be treated
  • 00:07:09 separately and I will rename this to on
  • 00:07:13 file change whatever you want to use
  • 00:07:17 with that we got our cloud function set
  • 00:07:21 up now let's simply test it and for that
  • 00:07:24 I'll open up the terminal it's the
  • 00:07:26 normal terminal just integrated into
  • 00:07:28 this IDE and you push this function into
  • 00:07:32 the cloud so that we can test it
  • 00:07:34 I'll run firebase deploy and this will
  • 00:07:38 now take my function code bundle it up
  • 00:07:40 upload it to firebase and set it up
  • 00:07:43 there so that we can then well basically
  • 00:07:45 use that function on firebase so let's
  • 00:07:47 wait for this to finish and let's then
  • 00:07:49 try it out the deployment process can
  • 00:07:53 take a while it finished for me let's
  • 00:07:55 now have a look at it in our firebase
  • 00:07:57 project console you can click on
  • 00:07:59 functions or refresh that page of your
  • 00:08:02 own reor or on it and there you should
  • 00:08:06 now see your newly deployed function on
  • 00:08:08 file change the function we just created
  • 00:08:11 you also see the attached event that
  • 00:08:13 it's on object change events you can
  • 00:08:16 also see the amount of executions and
  • 00:08:18 you can access the locks here that will
  • 00:08:21 become important to see what console
  • 00:08:23 lock actually wrote now let's try it out
  • 00:08:27 and let's go to storage and there we got
  • 00:08:29 our default bucket if we click on get
  • 00:08:31 started yeah we want to take these
  • 00:08:33 default settings this is our default
  • 00:08:35 bucket which will be used and let's now
  • 00:08:37 simply upload a file to it here I got a
  • 00:08:40 demo image which I will simply upload
  • 00:08:42 pick any image you want or can and can
  • 00:08:45 be any default doesn't have to be an
  • 00:08:46 image I'll use that image and it's now
  • 00:08:48 uploading and now this should have
  • 00:08:51 actually triggered our function so let's
  • 00:08:53 click on functions here and the
  • 00:08:55 executions amount might still show zero
  • 00:08:58 because it takes a little while to
  • 00:08:59 update this but if we view the logs here
  • 00:09:03 we should see the locks showing this
  • 00:09:06 execution of the function we we just
  • 00:09:09 encountered and this might also take a
  • 00:09:12 second and simply reload if it takes a
  • 00:09:14 bit longer now here you see we got an
  • 00:09:17 error that the function return undefined
  • 00:09:21 or a warning but we also see the
  • 00:09:23 console.log statement with the function
  • 00:09:26 where with this event object we output
  • 00:09:28 now there you see this event object
  • 00:09:31 actually had a data property which holds
  • 00:09:34 information about the bucket that issued
  • 00:09:36 this the content type of the file that
  • 00:09:38 changed and if we have a look through
  • 00:09:42 all of that we also see some additional
  • 00:09:44 like infrared digital information like
  • 00:09:46 the link to the file if you want to view
  • 00:09:48 it some metadata attached to the file
  • 00:09:50 and also the event type that it was a
  • 00:09:53 change event now let's see if does all
  • 00:09:56 the triggers for deleting so if we go
  • 00:09:58 back to storage let's now select this
  • 00:10:02 file and simply delete it and let's then
  • 00:10:05 again have a look at functions and view
  • 00:10:10 the locks let's see if this also
  • 00:10:13 triggered a function execution
  • 00:10:15 now thus far it doesn't look like it but
  • 00:10:17 here we go so as I said it might take a
  • 00:10:20 little while so this year this is the
  • 00:10:22 function that just executed here if we
  • 00:10:25 expand this here you see it's almost the
  • 00:10:29 same data but there's one important
  • 00:10:30 difference for the data here we get this
  • 00:10:34 resource state property which in this
  • 00:10:37 case is not exists if we have a look at
  • 00:10:40 the last function execution where we
  • 00:10:43 added this file there you see that the
  • 00:10:45 resource state was exists so this gives
  • 00:10:48 us an idea about which specific type of
  • 00:10:51 event we had here that in this case the
  • 00:10:53 file was deleted for example we could
  • 00:10:56 determine this by checking for the
  • 00:10:58 resource state here it doesn't exist
  • 00:11:00 anymore so if we want to run some
  • 00:11:02 function only upon the deletion of files
  • 00:11:04 this would be how we could well check
  • 00:11:07 for that so if there we can see how that
  • 00:11:10 function runs now let's do something
  • 00:11:12 more useful let's maybe start with
  • 00:11:14 renaming the file so we got this event
  • 00:11:18 object and we can see what's inside of
  • 00:11:19 it here it has a data property with some
  • 00:11:22 useful information and why don't we now
  • 00:11:25 take that file rename it and then put it
  • 00:11:27 back into the storage wouldn't that be
  • 00:11:29 an idea let's first of all retrieve the
  • 00:11:32 object by accessing event
  • 00:11:35 data because that essentially is our
  • 00:11:36 object data we got now here we can find
  • 00:11:40 out the bucket by accessing object
  • 00:11:43 bucket so I'm accessing this first
  • 00:11:45 property here we can also get the
  • 00:11:50 content type by accessing object content
  • 00:11:55 type and let's also get the file path
  • 00:11:59 here by accessing object name so fall
  • 00:12:04 path essentially is just the name here
  • 00:12:08 which will be not just a file name but
  • 00:12:11 also the path in this bucket now I'll
  • 00:12:14 add a console.log statement here and
  • 00:12:17 simply output file change detected
  • 00:12:22 function execution started just to have
  • 00:12:27 some locks happen in between so we can
  • 00:12:29 see where we are at and now I want you
  • 00:12:31 to take that file and basically put it
  • 00:12:33 back into the pocket with a changed name
  • 00:12:35 before that I need to install an
  • 00:12:37 additional package so navigate into the
  • 00:12:39 functions folder in your project folder
  • 00:12:41 and there i'll run npm install – – save
  • 00:12:45 and now it's at google – cloud slash
  • 00:12:50 storage which is a collection of good
  • 00:12:53 cloud storage on which firebase storage
  • 00:12:55 is built on functions and and methods we
  • 00:12:58 can use and one of them is basically
  • 00:13:00 putting data into a bucket and we need
  • 00:13:02 that functionality here
  • 00:13:03 so with that installed all imported as a
  • 00:13:06 dependency at the top GCS is require at
  • 00:13:10 Google Cloud slash storage and you
  • 00:13:16 execute this as a function and the cool
  • 00:13:18 thing is if you're in a cloud function a
  • 00:13:20 firebase cloud function that happens or
  • 00:13:24 is triggered upon a file change event
  • 00:13:26 you can use the Google Cloud search
  • 00:13:28 package here without having to
  • 00:13:30 initialize it with any credentials you
  • 00:13:32 can just start putting data into that
  • 00:13:33 bucket without any special setup
  • 00:13:36 required
  • 00:13:37 so what I'll now do is I will first of
  • 00:13:40 all create a new pocket I want to put it
  • 00:13:42 – so dist bucket maybe or destination
  • 00:13:47 pockets or something like that
  • 00:13:48 and I will use GCS and there we have a
  • 00:13:50 bucket method you set up a reference to
  • 00:13:53 a bucket and it will pass the bucket
  • 00:13:55 this fall was in because I want to keep
  • 00:13:57 it in the same bucket I just want to
  • 00:13:59 rename it as a next step I want to
  • 00:14:01 download that file which we uploaded
  • 00:14:04 which triggered this event so that I can
  • 00:14:06 then manipulate it and put it back into
  • 00:14:08 the bucket so I'll create a temp file
  • 00:14:12 path so this is just where I want to
  • 00:14:13 temporarily download it because and
  • 00:14:15 that's important to know in firebase
  • 00:14:17 cloud functions you got a small
  • 00:14:19 temporary storage which will be cleaned
  • 00:14:21 up whenever the function execution is
  • 00:14:22 done essentially but which you can use
  • 00:14:25 during the function execution now to
  • 00:14:27 find out the path for this we can use a
  • 00:14:29 node.js package which is called OS
  • 00:14:32 giving us X some operating system
  • 00:14:35 specific functions and I also want to
  • 00:14:37 construct the path so I'll use the path
  • 00:14:40 package node.js provides and with these
  • 00:14:43 two packages we can construct our
  • 00:14:45 temporary path by calling path join here
  • 00:14:49 and I want to join the temporary path
  • 00:14:52 off the operating system the function
  • 00:14:54 runs on which I can get with the temp
  • 00:14:56 tear function with the filename we got
  • 00:15:00 so the file name of our uploaded fault
  • 00:15:04 fault path is what I named it here now
  • 00:15:07 this path however is the full path Arjun
  • 00:15:10 what I just want to get the name I can
  • 00:15:12 do this with the path package and there
  • 00:15:14 with the base name method which I passed
  • 00:15:16 the file path to this will then just
  • 00:15:18 give me the file name part of the path
  • 00:15:21 so if that would constructed this
  • 00:15:23 temporary file path I want to store my
  • 00:15:26 file whilst the function here executes
  • 00:15:29 I'll then also create a metadata
  • 00:15:32 constant where I will essentially set up
  • 00:15:34 a JavaScript object where I set the
  • 00:15:37 content type q content types or the
  • 00:15:42 content type of god from the file so
  • 00:15:43 that we keep that and then I will no
  • 00:15:47 longer return nothing but I will return
  • 00:15:49 deaths bucket using that Cloud Storage
  • 00:15:53 package file which allows me to execute
  • 00:15:56 operation on a file the file here is my
  • 00:15:59 file path so the path we got
  • 00:16:02 the event that's triggered here and then
  • 00:16:06 I can call download now to download I
  • 00:16:10 need to pass some configuration here I
  • 00:16:14 had the configuration as to where I want
  • 00:16:16 to download it you do this by adding the
  • 00:16:18 destination key and here I want to set
  • 00:16:20 it to my temp file path of course to
  • 00:16:22 make sure that I download the file from
  • 00:16:24 my bucket into the temporary folder now
  • 00:16:27 this will return as a promise and of
  • 00:16:30 course I want to do something when this
  • 00:16:32 finishes so here in the den block I will
  • 00:16:36 know that the file has been downloaded
  • 00:16:38 now I can rename it and re-upload it or
  • 00:16:42 do whatever I wanted to it of course not
  • 00:16:44 just rename it we will do more to it
  • 00:16:46 later here however I will just rename it
  • 00:16:49 now renaming is simple I can just return
  • 00:16:52 desc bucket and call upload and put the
  • 00:16:55 file from the temp file path back onto
  • 00:16:58 the server and if this doesn't make too
  • 00:17:00 much sense here well it's a trivial
  • 00:17:02 operation we will soon add more logic
  • 00:17:04 than just downloading and uploading but
  • 00:17:05 these are the core building blocks you
  • 00:17:07 have to know so I will upload that file
  • 00:17:09 again it hasn't been renamed but I can
  • 00:17:12 rename it now I pass a configuration to
  • 00:17:15 the upload method where I also set up a
  • 00:17:17 destination and here I can just change
  • 00:17:20 the filename so here what I could do is
  • 00:17:22 I could add a renamed prefix plus my old
  • 00:17:26 file name maybe so I could use path base
  • 00:17:30 name of file path to again get dead to
  • 00:17:34 again get this original file name and
  • 00:17:35 now it would be the same file name with
  • 00:17:37 renamed sidenote if it was in a
  • 00:17:39 different path before it now isn't
  • 00:17:41 anymore because I dropped the path I
  • 00:17:43 could riad it in front of it but I don't
  • 00:17:44 want you there here and that is my
  • 00:17:46 destination
  • 00:17:47 now also setup the metadata key here to
  • 00:17:49 pass my metadata which essentially sets
  • 00:17:52 up the content type of the new file
  • 00:17:53 which should be the same content type as
  • 00:17:55 before and now with that I got my upload
  • 00:17:59 functionality here which eventually will
  • 00:18:02 finish and should put in a rename fall
  • 00:18:04 back onto the storage now before we
  • 00:18:06 tried it out let me add more code I want
  • 00:18:09 to add a if check here to make sure we
  • 00:18:10 don't enter an infinite loop I want to
  • 00:18:13 check if the Apple
  • 00:18:15 uploaded fall puffs the file name starts
  • 00:18:19 with renamed already so that I don't
  • 00:18:21 reach rigor the function for that
  • 00:18:22 renamed file so I will check if path
  • 00:18:25 base name for the fall path so for the
  • 00:18:29 path of the fall that triggered this
  • 00:18:32 cloud function if that starts with
  • 00:18:39 renamed so what we put to the fall here
  • 00:18:43 so that I don't reach rigor this if
  • 00:18:46 that's the case I simply want to return
  • 00:18:51 here I don't want to continue execution
  • 00:18:53 because now I know the file that changed
  • 00:18:57 is the file we just renamed I don't want
  • 00:19:00 to trigger a function again or otherwise
  • 00:19:02 we would enter an infinite loop which we
  • 00:19:04 certainly don't want you I will also log
  • 00:19:07 something here we already renamed that
  • 00:19:13 file now with all of that in place let's
  • 00:19:19 save this and let's see if that works by
  • 00:19:21 going out of the function folder in the
  • 00:19:23 terminal and rerun in firebase deploy to
  • 00:19:25 again push this updated version of the
  • 00:19:27 function back on to firebase cloud
  • 00:19:29 functions and this will simply replace
  • 00:19:31 the old version off that function will
  • 00:19:33 not be created as a new one will replace
  • 00:19:35 the old one instead now let's wait for
  • 00:19:38 this to finish and let's then try it
  • 00:19:39 again
  • 00:19:39 the deployment finished let's go back to
  • 00:19:42 our functions console here on firebase
  • 00:19:45 and we will still see the same function
  • 00:19:47 as before now we see the execution all
  • 00:19:49 is updated and I'll go to storage and I
  • 00:19:52 again will upload a file to it so let's
  • 00:19:56 click upload file and pick that same
  • 00:19:58 file as before put it there
  • 00:20:00 it's uploading here
  • 00:20:05 and here it is and now let's have a look
  • 00:20:09 at our functions log here so for the
  • 00:20:12 function let's view the locks and as
  • 00:20:15 always this can take a second before the
  • 00:20:17 logs show up here for the current
  • 00:20:18 function execution here it is however
  • 00:20:21 and you see we've got two executions
  • 00:20:23 here one at 9:27 15 and a couple of
  • 00:20:30 milliseconds and then a couple of
  • 00:20:31 milliseconds later now we all see we
  • 00:20:33 already renamed the file here so good
  • 00:20:35 thing we implemented the safe check
  • 00:20:36 because this was dysfunction running the
  • 00:20:39 second time for the updated file this is
  • 00:20:42 the function running the first time now
  • 00:20:44 let's have a look at storage and we
  • 00:20:45 should see two files in there now and we
  • 00:20:48 do
  • 00:20:48 that's the renamed winter and as you can
  • 00:20:50 see it has the same file size if we do
  • 00:20:52 it it's also the same image as you can
  • 00:20:55 see here on the right
  • 00:20:56 that's the original one and with that
  • 00:20:59 you'll learn how you can use that to do
  • 00:21:01 something with the incoming files you
  • 00:21:03 all learned that it's quite important to
  • 00:21:04 make sure you don't enter an infinite
  • 00:21:06 loop now let's do more useful stuff to
  • 00:21:09 the image though than just renaming it
  • 00:21:11 in this way I want to also resize it for
  • 00:21:14 this I'll use a library named image
  • 00:21:16 magic which contains a lot of
  • 00:21:18 functionalities we can use to change
  • 00:21:20 images in all different kinds of ways
  • 00:21:23 you'll find a link in the video
  • 00:21:24 description with more detail I'll just
  • 00:21:27 use it to resize that the cool thing is
  • 00:21:29 image magic already is pre-installed in
  • 00:21:32 the environment the cloud function runs
  • 00:21:33 in all we have to do is use a package
  • 00:21:36 that allows us to run basically tools
  • 00:21:40 binaries that are installed on the
  • 00:21:43 server the cloud function runs in the
  • 00:21:44 end it's a package called spawn which I
  • 00:21:49 require from a package I have to install
  • 00:21:52 and this will be called child process
  • 00:21:56 promise there we can then access the
  • 00:22:00 spawn property now let's install that in
  • 00:22:04 the functions folder so navigate in
  • 00:22:06 there and run NPM install – – save child
  • 00:22:09 process promise it's essentially a
  • 00:22:11 package that allows us to run any
  • 00:22:13 processes on the operating system of
  • 00:22:16 this function and get back a promise
  • 00:22:19 we'll never get out of the folder
  • 00:22:20 they're after and with that we can use
  • 00:22:22 that spawn here as a function to run
  • 00:22:24 well native programs installed on that
  • 00:22:28 server so to say I want to run such a
  • 00:22:30 program here when we downloaded the file
  • 00:22:33 there I want to return spawn and due to
  • 00:22:37 it coming from that child processes
  • 00:22:39 promise package this will give us back a
  • 00:22:41 promise I want to return spawn here and
  • 00:22:44 now pass con word that is a command we
  • 00:22:49 can execute on this system the firebase
  • 00:22:51 function random and it's coming from
  • 00:22:52 image magic so I want to run con word
  • 00:22:55 and then I has an array of arguments
  • 00:22:57 here to that convert command and that
  • 00:22:59 are simply commands the convert command
  • 00:23:02 or these are arguments to convert
  • 00:23:04 command understands like the input the
  • 00:23:08 filename basically so temp file path so
  • 00:23:10 the file we stored on the cloud base on
  • 00:23:13 the cloud function storage then the
  • 00:23:16 second argument is that I want to resize
  • 00:23:19 it we do this by – resize and third
  • 00:23:23 argument are the dimensions and the
  • 00:23:25 dimensions will keep the aspect ratio
  • 00:23:27 and we'll use the smaller of the two
  • 00:23:30 relevant sizes so let's say I want to
  • 00:23:32 resize this to 500 by 500 and again this
  • 00:23:35 will not necessarily spit out an image
  • 00:23:36 of size 500 by 500 it will simply try to
  • 00:23:39 fit the existing image into this format
  • 00:23:42 by keeping the aspect ratio and then I
  • 00:23:45 will specify where to store it well this
  • 00:23:48 will simply be the same file name so I
  • 00:23:51 will overwrite that local file I still
  • 00:23:54 want to upload that but this has to
  • 00:23:56 happen anew then call because again
  • 00:23:59 spawn returns a promise so I chained
  • 00:24:01 another then call and in this then call
  • 00:24:04 I know that the file will have been
  • 00:24:06 resized so I'll also name this resized
  • 00:24:10 and then simply upload it again just as
  • 00:24:13 before now since I named is too resized
  • 00:24:15 here I also have to update my check here
  • 00:24:18 resized and I will add a second check
  • 00:24:21 what if we actually deleted a file then
  • 00:24:23 we would fail here because we try to
  • 00:24:25 download a file we don't have so what
  • 00:24:27 I'll actually do first is I'll add
  • 00:24:29 another check here and simply check if
  • 00:24:33 object resource state equals not exists
  • 00:24:38 remember this was one value we could see
  • 00:24:41 here in the cloud function lock for one
  • 00:24:43 of our first executions where we could
  • 00:24:46 see that if we triggered a delete event
  • 00:24:50 that resource state would it be not
  • 00:24:53 exists so this is what I'm checking for
  • 00:24:55 here if that's the case we deleted a
  • 00:24:57 foul
  • 00:24:57 so I'll cool lock we deleted a file come
  • 00:25:02 on exit and there Arthur L also just
  • 00:25:05 returned because upon file deletion I
  • 00:25:07 don't want to do anything so these are
  • 00:25:09 two useful checks with then we should
  • 00:25:11 now resize the file and then upload it
  • 00:25:13 again
  • 00:25:14 so let's save everything here and let's
  • 00:25:15 again run firebase deploy to see this
  • 00:25:18 changed function in action deployment
  • 00:25:20 finished now let's try it out
  • 00:25:22 let's go to storage again let me first
  • 00:25:26 of all delete both files here both
  • 00:25:28 commands will now trigger our cloud
  • 00:25:30 function so it should execute here but
  • 00:25:33 it also should simply quit because we
  • 00:25:36 specified that we don't want to do
  • 00:25:37 anything if we have a delete event so
  • 00:25:40 let's simply wait for this and actually
  • 00:25:43 just didn't work as expected so let's
  • 00:25:46 have a look at the code here object
  • 00:25:49 resource state and actually it should be
  • 00:25:52 alright let's try this again later
  • 00:25:55 maybe the function just wasn't updated
  • 00:25:56 yet when I deleted this so let's try
  • 00:25:59 uploading a file now let's take the same
  • 00:26:01 file as before and actually we don't
  • 00:26:04 even have to go to the functions log
  • 00:26:06 here we could simply reload this page
  • 00:26:08 and we should see the resized file set
  • 00:26:10 next to our original file now and there
  • 00:26:13 we have it resized winter you see the
  • 00:26:15 file size is much smaller and if you
  • 00:26:17 access it there you see they file again
  • 00:26:21 now if we quickly download that file to
  • 00:26:25 inspect it locally you will see that the
  • 00:26:28 dimensions are 500 by 281 which simply
  • 00:26:31 means it took T 500 and adjusted e I
  • 00:26:34 don't want to keep the aspect ratio now
  • 00:26:37 let's simply see if that check here with
  • 00:26:39 not exists as really not work so back in
  • 00:26:42 our storage console here let's delete
  • 00:26:45 both files again
  • 00:26:46 let's see if again it just fails because
  • 00:26:49 it should now really not fail but simply
  • 00:26:53 exit because we well already deleted the
  • 00:26:56 files we deleted a file exit so this
  • 00:26:59 works fine so it wasn't updated to where
  • 00:27:01 time before this actually is it for this
  • 00:27:04 video you learned how to react to file
  • 00:27:08 changes how to make sure you react to
  • 00:27:10 the right changes and how you can then
  • 00:27:12 download that file manipulate it in
  • 00:27:14 which ever way you want it and put it
  • 00:27:16 back onto the pocket or not put it back
  • 00:27:18 just download it and do something here
  • 00:27:20 which doesn't make too much sense though
  • 00:27:22 because this local storage in the cloud
  • 00:27:25 function gets cleaned up once the
  • 00:27:27 function execution is done anyway so you
  • 00:27:29 learned a lot you can do with this file
  • 00:27:32 change event here now in the next video
  • 00:27:35 I want to have a look at creating a
  • 00:27:37 restful endpoint with the HTTP event