Quill deltas fit perfectly with Firebase

Collaborative documents in Vue

Brock Reece
3 min readOct 8, 2017

--

In this article, we are not aiming to rival Google docs, but in about 20 minutes we should be able to create a realtime collaborative document using Vue, Firebase and Quill.js

Quill.js is a text editor that uses deltas (json objects) to represent it’s markup and this fits perfectly into the way Firebase stores json data. Firebase is a database platform built by Google, that uses websockets to update it’s connected clients in realtime.

Vue-quill

I am a huge fan of Quill, so much so that when I switched to using Vue last year, creating a community wrapper for the JSON based text editor was high on my priority list. For this project, we will be using a relatively simple setup of vue-quill, first we will use yarn to add the lib to our project.

yarn add vue-quill

And then we will add the plugin to Vue in our main.js. The plugin will globally register a quill component that we will use later on.

# main.js
import Vue from vue
import VueQuill from vue-quill
Vue.use(VueQuill)
...

For more advanced configs see the vue-quill docs

Firebase and vuefire

I am new to Firebase and was amazed how simple the vuefire plugin made it to integrate it into my Vue project. I suggest you visit their project page for more examples, as we are only skimming the surface here. Like vue-quill, we will use yarn to add firebase and vuefire to our project.

yarn add firebase vuefire

And then we will add the vuefire plugin to Vue in our main.js

# main.js
...
import VueFire from 'vuefire';
...
Vue.use(VueFire)

Before we go any further, we will need to create a new database in the Firebase console, for this example I named my database ‘quill’. If you are new to Firebase, Google’s documentation will walk you through how to do this.

Building our Vue component

Below is the starting point of our app.vue. You will need to pass in your Firebase project’s config to the Firebase.initializeApp method, you can find these details from within the Firebase console by clicking on the Settings cog next to the Overview section in the left hand menu and choosing the Add Firebase to your web app option.

# app.vue<template>  
<quill ref="quill"/>
</template>
<script>
import Firebase from 'firebase';
const app = Firebase.initializeApp({
apiKey: '****',
authDomain: '****',
databaseURL: '****',
projectId: '****',
storageBucket: '****',
messagingSenderId: '****',
});
const db = app.database();
export default {}</script>

Vuefire helps us integrate our Firebase database by defining a firebase object in our Vue component. In our example below accessing this.quillContent from within this component will return the current value of our database.

...
export default {
firebase: {
quillContent: {
source: db.ref('/quill'),
asObject: true,
},
},
}
...

Realtime updates

Now we have set up our component, we will need to listen for changes in our quill component and update Firebase with our new delta. For this we will add a listener to the quill component and use lodash to debounce this update to 1 second after the user stops typing or making changes.

<template>  
<quill @input="updateFirebase" ref="quill"/>
</template>
<script>
import _ from 'lodash'
...
methods: {
updateFirebase: _.debounce(function (content) {
this.$firebaseRefs.quillContent.set(content);
}, 1000),
}
...
</script>

As Firebase pushes changes to it’s connected clients when a new delta is published, we will also need to listen for these changes. In a mounted method, we will register a watcher for quillContent that will update the contents of our quill component whenever a change is pushed out from Firebase

mounted() {
this.$watch('quillContent', (val) => {
if (this.$refs.quill) {
this.$refs.quill.editor.setContents(val, 'silent');
}
})
},

And that should do it, open up a couple of browser tabs and watch how your updates in one editor are replicated in the other tabs almost instantly.

Summary

This is a just a starting point, but hopefully I have introduced you to a few new technologies and techniques for you to go on and build a rich realtime collaborative web app.

--

--