Writing a Google Functions For Firebase Function

David Dal Busco
Jul 22 · 5 min read
Photo by samsommer on Unsplash

We are currently developing an open source web editor for presentations called DeckDeckGo which we’ll hopefully be able to release in beta around the end of the summer.

Why have I allowed myself to be so bold in my opening sentence? Well, here we go: I’m happy to officially announce that it will not just be an editor but also an online platform, a place where presentations can be shared and ultimately, if I let my self dream a bit about the future, are indexed according your interests and maybe even can be discussed.

We have a long way to go before we have such an application and community — but that doesn’t mean we can’t dream a bit, especially as this is a side project; we implement at night and on the weekends for fun.

So, we’ve decided to implement the first piece of this idea in our beta. The main screen, which I call the “feed”, will present all the decks that are going to be edited and published (as standalone Progressive Web Apps…but that’s another story) with our tool. For that purpose, as for their social cards, we decided to capture in the cloud a screenshot of the first slide of such decks.

In this blog post to show how to create a Google Functions for Firebase to take a screenshot of a website in the cloud.

A sneak peek of our feed filled with our test presentations

Introduction of the Solution

For this solution, we’ll write a new Google Functions for Firebase in order to run our process in the cloud. We are going to use Puppeteer to run a headless Chrome, where we’ll load the website, and take the screenshot. Finally we’ll write the results in Google Firebase Storage.

Before We Start

I t is true that Google published a good article in August 2018 which introduces the headless Chrome support in Cloud Functions and App Engine, and precisely describes how to take a screenshot. However, my post introduces the storage but also improves on the method of screenshot capture. So, I hope you still think this piece deserves your time!

In this tutorial I’m going to skip the part where you setup and interact with your Google Firebase Functions or Storage. There are dozen of documentations and tutorials about it and Google Firebase Console even has wizards to take you through the process. You’ll also note that I use TypeScript to write the functions and we’ll be writing all our code in the main file src/index.ts.

Getting Started

For the purpose of this article we are going to create an HTTP function which could, obviously, be invoked through HTTP. For DeckDeckGo, we are using a realtime database triggers to trigger the process.

import * as functions from 'firebase-functions';

export const takeScreenshot =
functions.https.onRequest(takeScreenShotOnRequest);

async function takeScreenShotOnRequest(request, response) {
// 1. Generate screenshot
// 2. Save to the storage
}

Take the Screenshot

As explained above, we are going to use Puppeteer to capture the screenshot. So, first we have to install the dependency and its type definition for typescript:

$ npm install puppeteer --save
$ npm install @types/puppeteer --save-dev

Once installed, we modify our previous code and implement the function:

What’s happening there? We’re telling Puppeteer to run a headless Chrome which accesses our website at a page with a specific size — the size (width and height) of our screenshot. We’re also disabling the service workers (“no cache = always fresh data”) and waiting for a particular element to be loaded before taking the screenshot. If your goal is to take a screenshot from a static website, you can skip that last step. Finally, we tell Puppeteer to take a screenshot and return the image buffer as result of the function.

Special Credits

I did not come to this neat solution on my own. It is the result of an exchange with Matthias Max, CEO of bitflower, on the StencilJS Slack channel. Kudos to him, I wouldn’t have thought to disable the service workers if he hadn’t shared his idea and code. Thanks a lot Matthias!

Tips and Tricks

In case you would need more memory to run your cloud function (it was the case for our project), you could extend the above declaration with, for example, 1GB of memory and a timeout of 2 minutes.

Save to Storage

Saving the image buffer to the storage is actually really easy (although I don’t know why I’m still surprised by the simplicity of Google Firebase!) Using the Firebase Admin, we just reference the default bucket, create a file object and save it.

Note: there is no need to check or create specific folders and subfolders — the library handles everything for you. Also, if you run the process multiple times, as per default, the resulting files in the storage are just going to be overwritten.

That’s it — we’ve implemented a Google Cloud Function to take and save a screenshot of our website.

Trying It Out

As I said above, I won’t go in the details of the interaction with Firebase. That being said, you could deploy your function running the following command in a terminal:

$ firebase deploy

You could also try it out running the following curl command in your terminal:

$ curl -i -H "Accept: application/json" -X GET  https://us-central1-your-cool-app.cloudfunctions.net/takeScreenshot

Replace https://us-central1-your-cool-app.cloundfuntions.net with your application/functions URL.

Cherry on the cake 🍒🎂

Our project is open source and we try to encourage others to do so too, which is why we released this particular function in our monorepo under the GNU Affero General Public License. Therefore, if your project is cool too be our guest and clone https://github.com/deckgo/deckdeckgo/tree/master/cloud .

To infinity and beyond!

David

Better Programming

Advice for programmers.

David Dal Busco

Written by

Creator of DeckDeckGo | Founder of Fluster | Organizer of the Ionic Zürich Meetup

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade