To the Stars with Quasar & Firebase - Initial Service & Structure

adamkpurdy

Adam Purdy

Posted on February 6, 2020

To the Stars with Quasar & Firebase - Initial Service & Structure

Table Of Contents

  1. Introduction
  2. Installation
  3. Firebase Configuration and Application Environment
  4. Structure
  5. Base Service
  6. Summary
  7. Repository
  8. About Quasar

1. Introduction

Firebase is Google's mobile platform that helps you quickly develop high-quality apps and grow your business. It helps you by allowing you to build apps fast without managing infrastructure and gives you functionality like analytics, databases, messaging, and crash reporting so you can move quickly and focus on your users.

It was initially created as a startup in 2011 and was publicly available in 2012. In October 2014, Google acquired Firebase, which evolved into a platform that has 18+ products and is currently being used by 1.5 million apps as of October 2018. source - Wikipedia.

This article intends to be a base source for the articles that follows it, as the nature of this series is to inform the developer on how to set up Firebase within the Quasar Framework. While this information intends to be a foundational step for getting started with Firebase inside of Quasar, this is just the surface and is highly advisable to always consult the Firebase documentation initially for guidance.

  • 1.1 Assumptions

Before we get started, a few assumptions are in order. Unless otherwise specified in the posts to follow in this series, a presumption of the Quasar project consists of using: Stylus, auto importing of components, and using the features of ESLint and Vuex.

Alt Text

Also, please be sure to keep your quasar-cli as current as possible.

$ npm i -g @quasar/cli@latest
Enter fullscreen mode Exit fullscreen mode

Also, if you're here you've done two things:

  • Chosen the Quasar Framework to be your Vuejs front-end component framework
  • Chosen Firebase at the minimum to handle your Quasar application's authentication... maybe more

And finally, if something is not directly mentioned moving forward, it's more than likely to be covered in either the Quasar docs, or the Firebase docs. An effort will be made to keep a watchful eye on concepts that specifically pertain to the integration of Firebase within the Quasar Framework. Still, if something is missing, there is also the #firebase channel on the Quasar Discord server. A final note, this code is for Vue v2 and Quasar v1.

2. Installation

If you're new to Firebase, you must create a Firebase account with a Google identity and create a project in the console.
Alt Text

Once you've gotten your account and project setup in Firebase, it's time to install dependencies in your Quasar app and start the configuration process.

Install Firebase to your Quasar application, preferably via yarn package manager:

$ yarn add firebase
# or 
$ npm install firebase
Enter fullscreen mode Exit fullscreen mode

A configuration object is needed to configure the Firebase SDK for initialization from the Firebase console.

You can get access to your Firebase config object at any time by:

  • Sign in to Firebase, then open your project.
  • Click the Settings icon, then select Project settings.
  • In the Your apps card, select the nickname of the app for which you need a config object.
  • Select Config from the Firebase SDK snippet pane.
  • Copy the config object snippet, then add it to your app's HTML.

or

  • In your console run: $ firebase apps:sdkconfig web

3. Firebase Configuration and Application Environment

Assuming you are developing an app that will live in a production environment, Firebase recommends creating separate projects in the Firebase console. One for production, one for dev, and even a public testing endpoint if you'd like. The point here is to keep production data safe from development.

The use of environment variables is used during Quasar's build process to identify which Firebase and other configuration information are needed given the desired build. Earlier in this article's history, the use of Qenv was used but has since become deprecated. Dotenv is now used to set up the application's environment variables.

yarn add -D dotenv
# or
npm install -D dotenv 
Enter fullscreen mode Exit fullscreen mode

Create a .env file per the instructions on their repository. This file will house all environment options based on your application needs. Following dotenv's suggestion, do not split up your .env files per environment. Here's what your .env file could look like.

Note - For Windows Users - You'll need to install an additional package called cross-env, and update your package.json script.

{

  "scripts": {
    "dev:win": "cross-env QENV=DEV quasar dev"
  }

}
Enter fullscreen mode Exit fullscreen mode

/.env

# DEVELOPMENT FIREBASE CONFIG
DEV_API_KEY=######
DEV_AUTH_DOMAIN=######
DEV_DATA_BASE_URL=######
DEV_PROJECT_ID=######
DEV_STORAGE_BUCKET=######
DEV_MESSAGING_SENDER_ID=######
DEV_APP_ID=######
DEV_API_ENDPOINT=######

# STAGING FIREBASE CONFIG
STAGE_API_KEY=######
...
Enter fullscreen mode Exit fullscreen mode

Take notice of the prefix, 'DEV', in the variable names. This will be used in our script to set our QENV variable.

Create or update your build script in your package.json file.

/package.json

{
  ...
  "scripts": {
    "dev": "QENV=DEV quasar dev",
    "lint": "eslint --ext .js,.vue src",
    "test": "echo \"No test specified\" && exit 0"
   },
  ...
}
Enter fullscreen mode Exit fullscreen mode

Per the Quasar documentation, we need to add our parsed values from our .env file. We also need to add our environment variables set during our build script to allow our config file to determine which config object to use.

/quasar.conf.js

const enviromentConfiguration = require('./src/utils/environmentConfig.js')
module.exports = function (ctx) {
  return {
    ...
    env: {
      QENV: enviromentConfiguration(process.env.QENV)
    }
    ...
Enter fullscreen mode Exit fullscreen mode

Finally, create a utils folder and create an enviromentConfig.js file.
This file takes our environment variable set in our build script that gets passed over from our quasar.config.js and uses it to determine which configuration will initialize the Firebase applications. Utilizing template string literals and aligning your environment variable names with the prefixes in your .env file.

/src/utils/environmentConfig.js

const ENV = require('dotenv').config().parsed
/*
  Use an environment variable set in package.json scripts to determine
  the applications runtime environment. Add more switch cases as
  need for additional environments. Remember, Firebase recomends supporting
  separate Firebase project for different application environments: httpsq://firebase.google.com/docs/projects/multiprojects#support_different_environments
*/

module.exports = (QENV) => {
  if (!['DEV', 'STAGE', 'PROD'].includes(QENV)) {
    throw Error('Unknonw or not supplied environment variable')
  }
  return {
    FIREBASE_CONFIG: {
      apiKey: ENV[`${QENV}_API_KEY`],
      authDomain: ENV[`${QENV}_AUTH_DOMAIN`],
      databaseURL: ENV[`${QENV}_DATA_BASE_URL`],
      projectId: ENV[`${QENV}_PROJECT_ID`],
      storageBucket: ENV[`${QENV}_STORAGE_BUCKET`],
      messagingSenderId: ENV[`${QENV}_MESSAGING_SENDER_ID`],
      appId: ENV[`${QENV}_APP_ID`]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Structure

Before we dive into setting up the code, let's take a second to illustrate and discuss a bit of the opinionated direction we'll be taking. The fact that we can simply import Firebase and all its needed services into a single boot file, or just import the service directly in our Vue file and build our functionality as needed is definitely an option moving forward. But, the attempt here in these next few articles is to guide the development into more of a separated and maintainable production approach. We want to separate our services by a single namespace, firebaseServices, and also have each contextual service in a file. We can lend our structure to small and manageable files, as well as writing tests.

Alt Text

We'll revisit this again as we add more contexts to the application.

The following code snippet is meant to highlight the initial approach of setting up your application by separating your server connection and the actual service itself. The next bits are not intended to set up any real functionality, but highlight the first necessary pieces of the application structure. A typical Quasar app structure is here.

5. Base Service

The first place to get Firebase into Quasar is starting in a boot file. Create a boot file, then add its name to the boot array in the quasar.conf.js. Be sure to read up on Quasar’s boot files here. It is a great review, and also the first place to start when debugging Firebase issues.

$ quasar new boot firebaseConnection
Enter fullscreen mode Exit fullscreen mode

/quasar.config.json

boot: [
  'firebaseConnection'
],
Enter fullscreen mode Exit fullscreen mode

Our boot file is not the Firebase service itself, but a point in which to bring in the Firebase service, in case you need or want to switch out your backend to another cloud provider or traditional backend API interface.

/src/boot/firebaseConnection.js

import firebaseServices from '../services/firebase'

export default async () => {
  const app = firebaseServices.fBInit(process.env.QENV.FIREBASE_CONFIG)

  // Validation that our service structure is working
  // with an initialize Firebase application and auth instance.
  console.log('Firebase App Instantiation:', app)
  console.log('Firebase Auth Module:', firebaseServices.auth())
}
Enter fullscreen mode Exit fullscreen mode

Calling the fBInit(process.env.QENV.FIREBASE_CONFIG) method is just a validation that the service structure is working, but does not guarantee that the initialization happened with a valid API key.

Create a new directory in our application structure called services, and put the base service inside.

/src/services/firebase/base.js

Throughout the next couple of articles, there will be a separation of each firebase service in relation to its context. These service file will be then be pulled into the /src/services/firebase/index.js file where we can have a top-level firebaseServices namespace via Object.assign().

Have a look here: /src/services/firebase

import firebase from 'firebase/app'
import 'firebase/auth'

/**
 * Returns Firebase's auth service
 * https://firebase.google.com/docs/reference/js/firebase.auth.html#callable
 * @returns {Auth} - The Firebase Auth service interface
 */
export const auth = () => {
  return firebase.auth()
}

/**
 * Convenience method to initialize firebase app
 * https://firebase.google.com/docs/reference/js/firebase?authuser=1#initializeapp
 * @param  {Object} config - FIREBASE_CONFIG during the build process
 * @returns {App} - Creates and initializes a Firebase app instance.
 */
export const fBInit = (config) => {
  return firebase.initializeApp(config)
}

Enter fullscreen mode Exit fullscreen mode

First, we import our Firebase SDK and separate the imports per Firebase product. Be sure to check out the complete list of products, click on the expansion item for "Available Firebase JS SDKs (using bundler with modules)". Likewise, we could import the entire SDK, but you can shave off KB's by importing the products separately. Also, keep in mind if you only import just the app portion of the firebase and NOT the other products you'll end up getting undefined errors when trying to work with those products.

The fBInit method allows Firebase to register a project that was created in the Firebase console.

Run the app:

$ yarn dev
Enter fullscreen mode Exit fullscreen mode

Remember if you're running Windows

$ yarn dev:win
Enter fullscreen mode Exit fullscreen mode

Once the app is finished building, it will launch to http://localhost:8080/#/.

If you have successfully instantiated the Firebase service you will see this:
Alt Text

Otherwise, your application will fail to initialize and you will have a Quasar boot error and a Firebase error message stating you have an invalid key.
Alt Text

The Firebase API key doesn't get validated until an authentication method is executed. This will be highlighted in the Email Authentication article.

6. Summary

Here is the start of our integration between Firebase into the Quasar Framework and highlights getting a project created in the Firebase console, setting up the basic structure for our firebaseConnection and our base Firebase service files. This base service is ready for future application needs. It will serve as a starting point for any Firebase type of authentication or any of the other services that Firebase offers.

7. Repository

Quasar-Firebase Repo: Base Service

Up next: Email Authentication

8. About Quasar

Interested in Quasar? Here are some more tips and information:

More info: https://quasar.dev
GitHub: https://github.com/quasarframework/quasar
Newsletter: https://quasar.dev/newsletter
Getting Started: https://quasar.dev/start
Chat Server: https://chat.quasar.dev/
Forum: https://forum.quasar.dev/
Twitter: https://twitter.com/quasarframework
Donate: https://donate.quasar.dev

💖 💪 🙅 🚩
adamkpurdy
Adam Purdy

Posted on February 6, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related