Gridsome + Firebase: Starter for your next static yet dynamic site

Gerard Lamusse
DAY4
Published in
5 min readMay 6, 2019

https://github.com/u12206050/gridsome-firebase-starter

UPDATED: The Gridsome Firebase Starter now includes the gridsome-source-firestore to build static pages and content with data directly from Firestore.

What is Gridsome?

Gridsome is a Vue based framework for building lightning fast static websites. Using data from your CMS, Markdown or any available data API and populating a GraphQL database, Gridsome generates and builds your website based on pages and templates you create. READ MORE

Courtesy of Gridsome (https://gridsome.org/docs/how-it-works/)

The Benefit

In short we can build a highly reactive dynamic website that is statically generated. Using the reactivity of Vue and Firesync(more below) you can easily manage your Firestore subscriptions throughout your app for both public and private users, whilst having all the speed and features of a statically built site on what ever CMS/API you want.

Static & Dynamic Site?

So like myself, when I started this project, you might ask: What is the use case for using a realtime data service like Firebase’s Firestore with a static site generator like Gridsome?

In my case we have pages and content which makes sense generating static sites for, but we also have pages that are unique per user, account and order history pages. We also have parts of the static pages that have dynamic content for example comments and a list of recent articles.

So let’s build a static and dynamic site with support for Users using Firebase Authentication, Real time data using Firestore and any other functions you might need using Cloud Functions.

Getting started

I assume you already know what Firebase is and how to setup a new project.

Firebase

  1. Run npm install -g firebase-tools Firebase cli
  2. Create your project folder mkdir my-project
  3. Navigate to your project folder cd my-project
  4. Run firebase login
  5. Run firebase init

Gridsome

If you don’t have Gridsome installed run npm install --global @gridsome/cli

Make sure you are inside your my-project directory then:

  1. Create the Gridsome site with the gridsome create website https://github.com/u12206050/gridsome-firebase-starter.git
  2. Navigate into the website folder cd website
  3. Copy the .env.example file and rename to .env.development
  4. Update the .env.development with your firebase credentials
  5. Run gridsome develop to start a local dev server at http://localhost:8080
  6. Continue with the Gridsome docs to create pages and templates

Firesync store

Q: What is Firesync store?
A: Well, it consists of two files. store.js and firesync.js , what it is, is essentially a reactive store with a set of functions to keep your entire app or even just single components in sync with collections from Firebase’s Firestore. Let me explain:

store.js creates a simple Vue store that you can use via this.$store the file. Feel free to add other properties to it as you need. Properties on this simple store are reactive and can easily be updated as normal reactive properties on a local component, eg. this.$store.name = "John Doe" However you may also define your own functions on the store object which is what firesync.js does and then use them as mutators or actions as you would in Vuex.

firesync.js adds a set of functions to either the $store object or the Vue.prototype class, meaning to all Vue components. There is a set of three functions that are exported from firesync.js and being used by fire.js, which is the file that sets up the Firebase connection. These three functions are there to help you subscribe to collections based on three states within your app. Within each of these three functions you can add the subscriptions you want to add and remove. These three functions are:

onInit

Subscribe to collections as soon as a Firebase connection is established. For example, retrieve the latest headlines, messages or exchange rates.

onInit(db) {
/** Add public subscriptions here */
store.$bind(db.collection('rates'), 'rates', () => {
if (Array.isArray(store.rates)) {
store.loadedExchangeRates = true
}
})
}

onLogin

Subscribe to collections/document once a user is logged in. Useful for fetching the user’s profile and having that available on as this.$store.user

onLogin(db, uid) {
/** Add private, user only subscriptions here */
store.$bind(db.collection('users').doc(uid), 'user')
}

onLogout

Unsubscribe from the subscriptions you added in the onLogin function. You can also give a default value to update the property with.

onLogout() {
/* Unsubscribes from private subscriptions */
store.$unbind('user', null)
}

$Functions

We use the $ sign to prefix functions that are available on the `$store` and Vue scopes. On every Vue component/view you have access to the following:

this.$db: Used for creating references and fetching data from Firestore.

const filteredDocsRef = this.$db.collection('documents').where('words', '>', 100)

this.$bind: Bind the results of a Firestore reference to a property on the current component

this.$bind(filteredDocsRef, 'documents')

this.$unbind: Unbinds the property on the component so it no longer gets updates. The second argument is optional, use it to update the property otherwise it stays unchanged with the last content that it had.

this.$unbind(‘documents’, [])

this.$store A global simple store used for storing dynamic data fetched from Firestore. However you can use it to sync any data throughout your app.

this.$store.user

The same two functions are available on the global store

this.$store.$bind(ref, property, cb?)

this.$store.$unbind(property, value?)

Firebase Functions

this.$functions: Most commonly used for creating requests to Firebase functions. Same as firebase.functions()

this.$functions.httpsCallable('getTime')().then(time => {
this.$store.currentTime = time
})

Firebase auth

this.$auth: This is extended on the firebase.auth() object which besides the logout() function and currentUser property it also has:

this.$auth.isLoggedIn: If the user is logged in or not

this.$auth.userId: The user id of the currently logged in user

this.$auth.roles: An object of roles the user has been assigned

Firebase Firestore

this.$firestore: Contains the useful field properties to use when writing to db. Some of these field properties:

new this.$firestore.GeoPoint(latitude, longitude) Creates a new immutable GeoPoint object

new this.$firestore.Timestamp(seconds, nanoseconds) Creates a new timestamp.

this.$firestore.FieldValue Read more

--

--