How to create role based accounts for your Saas App using FEAN? (Part 1)

Gilbert Mpanga
SaasArena
Published in
4 min readOct 18, 2018

FEAN is (Firestore + Express + Angular + Node) never mind :)

“programming language codes” by Markus Spiske on Unsplash

Most Saas apps involve roles of certain kinds. These can be administrative roles, others economic in nature such as Premium user, a freemium user. You can determine who has access to what. Maybe (article, certain features). Roles can be easily achieved in Firestore database. Firestore is a no-sql database hosted on and managed on the Firebase platform, its fast, super easy to learn. You can build rich real-time features and so much more.

We are going to build a simple Role based app only with angular for the front-end, node.js and firestore for the backend.

TL;DR

  1. Setup firebase in your angular app and express js
  2. Download private json key from firebase
  3. Configure your backend for firestore
  4. Create users collection
  5. Create express endpoints
  6. Add custom claims to add roles
  7. Deploy Express app to Google App engine
  8. Conclusion

Setup firebase in your angular app and express js

// Front-end
ng new exampleApp
cd exampleApp && cd exampleApp
// For adding firebase to angular app
ng add angularfire2
// Backend
mkdir backendApp && cd backendApp
yarn init
yarn add express body-parser firebase-admin
cd backendApp && touch app.js; touch controllers.js
app.use(cors());
app.use(helmet());
app.use(compression());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.post('/app/create-user',(req,res) => {res.send('Working');});app.listen(3000,() => {
console.log('App started at 3000');
});

Download private json key from firebase

Log in your firebase account navigate ProjectOverview > Users and Permissions > service accounts download your private JSON key, save it in a file, name it anything, in this tutorial I named mine config.json.

Configure your backend for firestore

const admin = require('firebase-admin');
const serviceAccount = require("./config.json");// private json key
// Initialize firebase admin sdk
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "GET-THIS-FROM-FIREBASE"
});
/*
Set this as there new update in a way firestore sets timestamps in collections
*/
const firestoreConfig = admin.firestore();
firestoreConfig.settings({
timestampsInSnapshots: true
});
// Create user collection
const userCollection = admin.firestore().collection('userCollection');

Create express endpoints

/*
create verify middle to check validity of token returned from angular app
*/
const verify = () => {
return (req,res,next) => {
let idToken = req.get('Authorization');
admin.auth().verifyIdToken(idToken).then((claims) => {
if (claims.uid) {
next();
}
}).catch(error => {
res.send({message: 'Invalid user'}).end();
});
}
};
app.post('/app/create-user',verify(),(req,res) => {let body = req.body;
userCollection.add({
fullName: body.fullName,
shortBio: body.shortBio,
isPremium: body.isPremium // boolean
}).then(results => {
res.send({message: 'Successfully created account'})
}).catch(error => {
res.status(500).send({message: 'Something went wrong'});
});
});

Add Custom claims to enable roles

Add a line with method setCustomClaims() that sets a filed isPremium . We will use this while logging in to separate features for freemium and premium users.

const verify = () => {
return (req,res,next) => {
let idToken = req.get('Authorization');
admin.auth().verifyIdToken(idToken).then((claims) => {
if (claims.uid) {
admin.auth().setCustomUserClaims(user.uid, {
isPremium: req.body.isPremium
}); // Set boolean to toggle between freemium and premium
next();
}
}).catch(error => {
res.send({message: 'Invalid user'}).end();
});
}
};

Deploy to app engine

We are going to Google App Engine. App Engine is a PAAS platform that you can use to host your web applications, it’s easy to use and helps you quickly spin up MVPs or full products hence it enables you focus on building and shipping your product instantly.

// Assuming you installed Google cloud CLI do the following:> gcloud init // this sets up and configures your project to be 
// delivered to google cloud
> cd backendApp && touch app.yaml
// app.yaml is required for App engine to set up environment and
// in app.yaml
runtime: nodejs
env: flex> gcloud app deploy
// you will be prompted for extra configurations like deployment
//zone location in that case you can choose US-EAST,EUROPE_WEST etc
// Your app will be successfully deployed

Here’s the full source code

const express = require('express');const cors = require('cors');const helmet = require('helmet');const compression = require('compression');const bodyParser = require('body-parser');const admin = require('firebase-admin');app.use(cors());
app.use(helmet());
app.use(compression());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// Read token from headers set by angular frontend
const verify = () => {
return (req,res,next) => {
let idToken = req.get('Authorization');
admin.auth().verifyIdToken(idToken).then((claims) => {
if (claims.uid) {
next();
}
}).catch(error => {
res.send({message: 'Invalid user'}).end();
});
}
};
app.post('/app/create-user',verify(),(req,res) => {let body = req.body;
userCollection.add({
fullName: body.fullName,
shortBio: body.shortBio
}).then(results => {
res.send({message: 'Successfully created account'})
}).catch(error => {
res.status(500).send({message: 'Something went wrong'});
});
});app.listen(3000,() => {
console.log('App started at 3000');
});

(To be continued) I’ll build the frontend app in part2.

Thanks for making this far , hopefully this has given you some hacks you will use next time while developing your Saas App. In case you need to add payments checkout our startup Cheqqly. We currently under YC startup school and our dream me and my co-founder is to enable Startups to receive payments from anywhere regardless where the startup is from.

Further reading

For App payments checkout https://www.cheqqly.com/

Official cloud firestore docs https://firebase.google.com/docs/firestore/

More on custom claims https://firebase.google.com/docs/auth/admin/custom-claims

--

--

Gilbert Mpanga
SaasArena

I write about software, life and everything between.