Module

admin-bro-firebase-functions

Plugin that allows you to render AdminBro by Firebase Cloud Functions

Installation

Before you start make sure you have the firebase app set up (https://firebase.google.com/docs/functions/get-started):

yarn global add firebase-tools
firebase login
firebase init functions
cd functions
// you might need to change version of node to 10 in your package.json
yarn add admin-bro admin-bro-firebase-functions

Usage on emulator

To run AdminBro locally use buildHandler factory method:

const functions = require('firebase-functions')
const { buildHandler } = require('admin-bro-firebase-functions')

// assume that you kep all you AdminBroOptions in this file
const adminBroOptions = require('./admin/config')

const onRequestHandler = buildHandler(adminBroOptions, {
  region: 'us-central1',
  before: async () => {
    // connect with database here (i.e.)
    // if this function returns something - it will replace
    // adminBroOptions passed as first argument to buildHandler
  },
  auth: {
    secret: 'super-secret-string-which-encrypts-session',
    authenticate: async (email, password) => {
       // find user and check password
       return foundUser
    }
  }
})

exports.app = functions.https.onRequest(onRequestHandler);

And this is it - you have working AdminBro instance which can be checked by running:

yarn serve

Deploy script

AdminBro bundles custom components to ./.adminbro folder. In other plugins (admin-bro-expressjs, admin-bro-hapijs) this is done on the server side. On firebase we cannot write files in project directory so we have to bundle files manually before the deployment.

In order to do this create a simple bundle script in ./bin/bundle.js file:

// ./bin/bundle.js
const AdminBro = require('admin-bro');

// assume that you keep all your AdminBroOptions in this file
const adminBroOptions = require('../admin/config')

const admin = new AdminBro(adminBroOptions);
admin.initialize();

and run this script before the deployment with NODE_ENV set to production.

To simplify it, you can update scripts in your package.json file like this:

{
  "scripts": {
    "bundle": "NODE_ENV=production node bin/bundle",
    "deploy": "yarn bundle && firebase deploy --only functions && rm .adminbro/bundle.js"
  }
}

After successful deploy we remove generated bundle.

Now simply run:

yarn deploy

and in a minute you will see your app on Google Cloud Functions for Firebase

Do this even better.

AdminBro serves 3 assets:

  • global.bundle.js which contains react, readux, axios etc.
  • app.bundle.js where entire AdminBro frontend resides
  • components.bundle.js - this is the place for bundled (with AdminBro.bundle) custom components (admin.initialize(); creates it in ./adminbro/bundle.js)

So it means that your function will have to serve these 3 assets every time user opens page with web browser.

You can change that by setting AdminBroOptions.assetsCDN. So before the deployment you can copy those files to public directory and host this directory via firebase hosting. Next point AdminBroOptions.assetsCDN to the hosting url and you will save this 3 extra calls to your function.

First you will need to add firebase hosting to your app and setup it to host files from ./public directory

This is how updated ./bin/bundle.js could look like:

const AdminBro = require('admin-bro');

// assume that you keep all your AdminBroOptions in this file
const adminBroOptions = require('../admin/config')

const admin = new AdminBro(adminBroOptions);
fs.copyFile(
  './node_modules/admin-bro/lib/frontend/assets/scripts/app-bundle.production.js',
  './public/app.bundle.js',
);
fs.copyFile(
  './node_modules/admin-bro/lib/frontend/assets/scripts/global-bundle.production.js',
  './public/global.bundle.js',
);
admin.initialize().then(() => {
  fs.rename('./.adminbro/bundle.js', './public/components.bundle.js');
})

and updated deploy script:

"deploy": "yarn bundle && firebase deploy --only functions,hosting"

View Source admin-bro-firebase-functions/index.js, line 1

Methods

# buildHandler(adminOptions, options) → {BuildHandlerReturn}

Builds the handler which can be passed to firebase functions

usage:

const functions = require('firebase-functions')
const { buildHandler } = require('admin-bro')

const adminOptions = {...}
const region = '...'

exports.app = functions.https.onRequest(buildHandler(adminOptions, { region }));

Parameters:
Name Type Description
adminOptions AdminBroOptions

options which are used to initialize AdminBro instance

options BuildHandlerOptions

custom options for admin-bro-firebase-functions adapter

View Source admin-bro-firebase-functions/src/plugin.ts, line 35

function which can be passed to firebase

BuildHandlerReturn

Type Definitions

object

# BuildHandlerOptions

Properties:
Name Type Attributes Description
region string

Region where function is deployed

before function <optional>

Optional before async hook which can be used to initialize database., if it returns something it will be used as AdminBroOptions.

auth object <optional>

custom authentication option. If given AdminBro will render login page

secret string

secret which is used to encrypt the session cookie

authenticate function

authenticate function

maxAge number <optional>

For how long cookie session will be stored., Default to 900000 (15 minutes)., In milliseconds.

View Source admin-bro-firebase-functions/src/plugin.ts, line 150