Use Firebase Cloud Functions to fetch an image and transform it to base64
Have you done image manipulation on a server?
That was one requirement I had a while back that I didn’t know how to solve at the moment.
We were working with jsPDF
to create report PDFs in one of our Ionic apps, but we had an issue, all of our images
where stored online, and you can’t pass a url to jsPDF
for images.
It only takes base64, data URI, and I think the blob object.
Our first try was to do the base64 transformation client side, and send all those strings to create the PDF. The issue was that if we had more than 10 images it started to lag.
So we decided to move this server-side, and created a Cloud Function that handled it for us.
For that, we need a Cloud Function that:
- Listens to the database for when we add the regular images URL.
- Resizes that image so that we don’t store something to heavy.
- Transforms it to base64.
- Stores the base64 string in the database.
With that in mind, let’s jump into coding, this article asumes you already have a project and have Cloud Functions initialized, if not, go through this article first.
Installing the packages we need
The first thing we’ll do is to install the packages we need, in our case those are two, we used the request
package to
fetch the image URL, and the sharp
package to resize it.
And then, import them both at the top of the functions file
We’re using encoding: null
to tell request that you want a Buffer, not a string. We need that buffer to create the
base64 string.
Create the Cloud Function
We want to first create the function that listents to the database, with a few checks in place. In our case, we had a projects collection and each document had a before and after picture we needed for the report:
Then we want to check, if we are updating anything else on that project and we already have that base64 property, we want to stop the function there.
Then we want to ask, if there’s no before picture, or no after picture and convert those to base64.
We’ll call a function to do the transformation, we’ll cover that as soon as we’re done with the cloud function that talks to the database.
Now, let’s talk about the toDataURL()
function, since all the image transformation is happening there.
First, we need the function to take the online url as a parameter, and return a Promise, since we’re going to be doing asynchronous things.
Then we’re going to use the request
module to fetch that image, if there’s no error and everything went well, we do
the image manipulation, if something’s wrong, we throw the error.
Then, we’re going to resize the original image, remember, a Firestore document has a hard limit of 1MB in size, and a base64 image is usually 30% heavier than the original one.
We’re using the sharp
module to resize it, we’re passing the height and width we want for the image, and then making
sure that response is also a buffer.
And lastly, we’re forming our base64 string:
And that’s it, the toDataURL(url)
function will return a valid base64 string we can then store in Firestore and use
for our pdf manipulation :)
Do let me know if you have any issues with this one, it was a major pain for us, we tried several different things before arriving to this.