The Simplest Backend for my App — The Senior Newbie Quests

Marco Muccinelli
5 min readNov 27, 2018

--

As an app developer, I often need a remote backend. I have almost no competence about servers and server-side programming, so I need the simplest solution I can deal with. I used to have a Parse account, so I started googling for a Parse.com replacement. I don’t want to install a Parse JS server — too complex for my actual skills and needs.

I found Google’s Firebase has many attractive pros:

  • generous free tier and scalable paid one;
  • tedious features to setup are available out-of-the-box — e.g.: users and their authentication, push notifications, etc.;
  • remote logic — e.g.: cloud functions;
  • platform specific APIs.

Preliminary steps

  1. Register to Firebase with your Google account.
  2. Create a new project on Firebase Console.
  3. At this point you have already access to SDKs, database, user authentication, etc. with no costs.

Going deeper

Cloud functions allows you to run your remote logic in a few ways:

  • a function can be triggered by a platform event — e.g.: a database record is inserted and you want to fire a push notification;
  • you can call a function via SDK or HTTP request;
  • you can exploit HTTP features to host Node.js apps — at this time Node.js 6 is officially supported and Node.js 8 is in beta.

First of all, let’s install Node.js and Firebase Tools. If you are on a Mac, I suggest you to install Homebrew and then to run these commands:

$ brew install node
$ npm install -g firebase-tools

Don’t worry: npm is just a dependency package manager. If you experience compilation issues, try to use --build-from-source flag.

Now you can use Firebase CLI Tools in order to setup an hosting project:

$ cd your/development/folder
$ mkdir my-project-name
$ cd my-project-name
$ firebase init hosting

Follow the wizard by associating your Firebase project.

Now you can add functions to your project:

$ firebase init functions

I’ll choose TypeScript language — a superset of JavaScript which supports type checking, error checking, and transpiles to JavaScript — because I am more accustomed to a type-safe environment.

Project structure: in functions you have dynamic content; in public you can put static files. Please note that, if you use version control — e.g.: Git — you may want to exclude node_modules path.

Installing Express.js

Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.

You have got me on minimal! Let’s install it:

$ cd functions
$ npm install express firebase-admin@latest firebase-functions@latest --save

Now you have to tell Firebase to call Express whenever an HTTP request comes in. You do so by adding a rewrites section to firebase.json.What is more, we will enable Node.js 8 beta support — by adding engines directive to functions/package.json — and we will change TypeScript transpilation to ES2017 — by modifying functions/tsconfig.json.

Let’s actually instantiate Express in functions/src/index.ts:

So, every time it comes a request, it will be rewritten to call app and, eventually, app will offload request to an Express instance. You could test locally by running:

$ cd functions
$ npm run serve
If you try to browse to the local web server you will get an error: this is normal, because you still need to setup routes.

Adding routes

First of all, let’s create a basic root route.

This means: for the HTTP verb GET, for path /, send as response this string.
MIME Type is text/html

You can specifically send JSON as response, by using res.json method:

MIME Type is application/json

It is crucial to pass parameters through URL and you can do it capturing path parameters. Values can be retrieved inside req.params:

Results of calling […]/app/hello/Marco

Using cache

In your Express handler you can set response header to enable CDN cache:

According to RFC-2616:

  • publicindicates that the response may be cached by any cache.
  • max-agespecifies the maximum amount of time (in seconds) this resource will be stored in user's browser.
  • s-maxage: for a shared cache (but not for a private cache), the maximum age specified by this directive overrides the maximum age specified by either the max-agedirective or the Expiresheader. So it says how long this resource will be stored in the CDN.

Render views

Instead of sending back responses manually we can set up views. Please note that Firebase Hosting gives precedence to static files contained in publicfolder.

First of all we have to install rendering engine dependencies:

$ cd functions
$ npm install handlebars consolidate --save

Then, on the top of index.ts, we can import engines:

We will enable Handlebars as default engine:

From now you can start to create your views inside functions/views path. Handlebars syntax is really minimal — starting from a simple {{expression}}. To render a view, you will call res.render():

Results of calling […]/app/goodbye/Moon

Integrating with Firebase features

Here’s the kicker: you can link to and leverage other Firebase functions. You only need to import and to initialize Firebase Admin SDK.

Say you have created a Cloud Firestore database through your Firebase Console UI, you can access it from Express easily.

Creating a more user-friendly view with Handlebars is a chance to start to structure your project a bit more. Inside src you will create subpaths to contain model classes — to represent data — and gateway classes — to isolate data retrieving logic.

Deploying to Firebase server

Last step before to upload code to Firebase is to remove (or rename)public/index.html, that would collide with / route. Then, we can call:

$ firebase deploy
Our Node.js 8 serverless API is ready and live

Sources

--

--

Marco Muccinelli

Call me Muccy. I’m a Senior iOS Developer.

Recommended from Medium

Lists

See more recommendations