Migrating From Firebase Functions to App Engine

Matt Carroll Jun 24, 2018

Why migrate?

Firebase functions are great for certain applications and can be great for chat apps, but cold start times can seriously hinder chat apps that aren’t used often leading to ~10s cold start times. With the launch of App Engine Standard environment for Node.js you can now get better cold start times and still be in Google Cloud’s free tier.

What are you moving?

Some small Node.js projects for chat and voice applications. For all my projects, the function is stateless and authentication is stored/retrieved in the Firestore or a similar database.

Migrating the code

The Firebase function framework uses Express and parses the request with body-parser for you (this is for HTTP triggers, you can also set pub/sub messaging or database event triggers). To tap into this you have to install the firebase-functions and firebase-admin npm modules in your project and the function that is called is referenced like this:


const functions = require('firebase-functions');
const admin = require('firebase-admin');

exports.functionName = functions.https.onRequest((req, res) => {
  // Your function here
}

The function can call other functions, include other libraries, other files and make network requests (you need to enable billing to make calls outside of Google’s network). To move from Firebase functions (the official name is “Cloud Functions for Firebase”, phew) we need to replicate the Express and body-parsing wrapping that Firebase functions does and pass the request and response objects to the new App Engine function to handle HTTP requests.

Here is Google’s “hello world” sample for Node.js App Engine standard environment and with the addition of JSON body parsing we come up with this app.js file:


const express = require('express');
const bodyParser = require('body-parser')

const app = express();

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))

app.use('/', (req, res) => {
  // Your function here
});

const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});

Copy your function and add any non-Firebase dependencies into a new package.json file for your App Engine project and npm install. Now you can try it out with node app.js to see how it works locally (on port 8080).

Lastly we’ll need to create a app.yaml file to tell App Engine how to deploy our code:

runtime: nodejs8

Yep. That’s it! Save it and we can go on to deploying…

Deploying

App Engine and all of Google Cloud Platform uses the Cloud SDK to manage deploying code. Its pretty similar to the Firebase CLI. First we need to install it which is pretty easy. Next run

gcloud init

and authorize access to your Google account and select the Google Cloud project you want to use. Next you run the command to deploy your app (make sure you’re in the directory with the app.js and app.yaml files):

gcloud app deploy

That’s it! After a few minutes the app should be deployed on App Engine on a public HTTPS URL.