vue-computed-firestore
v0.3.2
Published
Module to provide two-way binding between vue.js and Google firestore
Downloads
11
Readme
vue-computed-firestore
Simple two-way(ish) binding of firestore docs and collections to vue computed properties.
Install
npm install vue-computed-firestore
Usage
Somewhere in your apps boot process
const VueComputedFirestore = require('vue-computed-firestore');
Vue.use(VueComputedFirestore, {firebase: appFirebase});
Component
<template>
<h3>{{user.name}}</h3><br>
<input v-model.lazy="user.bio" />
<div v-for="(todo, key) in todos" :key="key" >
{{todo.text}}
</div>
</template>
<script>
export default {
data(){
return {
currentUserID: 'abc123',
},
},
computedFirestore(){
return {
user: ['user', '$currentUserID'],
todos: ['user', '$currentUserID', 'todos'],
}
},
}
In the above example, the user
and todos
defined within computedFirestore become reactive properties on the vue instance root (just like computed or data objects) and will update whenever the database changes.
Options
Options can be passed to this module in multiple ways
- As the second parameter to
Vue.use
- As a object with the key
$config
within thecomputedFirestore()
return object - As an object at index 0 within a property path array
Available options
firebase
Root firebase object to read from (required param forVue.use
)baseName = '$fs'
Internal property added to Vue prototype. Only changeable during install. Only modify this if there are conflicts.definitionName = 'computedFirestore'
String name of function called to create bindings. Only changeable during install.includeKey = '$key'
Whether to include theid
of a document, and it's keypath if included. Set to a falsy value to not include, otherwise it will be included as a non-enumerable property on the document.includeMetadata = '$metadata'
Whether to include document snapshot metadata, and it's keypath if included. Set to a falsy value to not include, otherwise it will be included as a non-enumerable property on the document.collectionsAsObject = true
Whether to return collections and queries as objects (using document id's as keys) or arrays.handlers = {}
See section below on handlers.
Property paths
The core of this modules use comes in defining property paths. Property paths are an array (optionally starting with a config
object) of strings (document and collection IDs), arrays (where
queries) and objects (orderBy
and limit
clauses).
Reactivity is added through property interpolation. Any place that can accept a string can be made to accept a reactive object by providing a string beginning with '$'
e.g., To retrieve a doc matching a computed, prop, or data value id
, you can use a property path like ['user', '$id']
. lodash.get is used internally to access this property, so dot-notated paths are acceptable.
Documents & Collections
Fetching documents and collections by ID is done by passing a string containing the ID to fetch. This can obviously be nested as required.
['users','$id','todos']`
would fetch the todos collection on the current user document
Where
Where-style queries are performed by using an array in the property path. The three elements of this array correspond to the three parameters in a firestore where query.
['users', '$id', 'todos', ['due', '<', Date.now()], ['completed', '==', '$showCompleted'] ]
would show the users todos that were due in the past either (depending on the value of
this.showCompleted
) been completed or were not completed.OrderBy and Limit
OrderBy and limit clauses are performed by using an object in the property path. This object can have one or both of
orderBy
andlimit
keys.limit
must be a number (or link to a reactive property which is a number), whileorderBy
can be a string (field name) or array (field name and ordering).['users', '$id', 'todos', ['completed', '==', false ]{ orderBy: ['due', 'asc'], limit: '$numberToShow'}]
will only show
this.$numberToShow
uncompleted todos, order by the date they're duePer-property config
If the first element of the property path is an object, it is treated as a config object, which overwrites any global or component-scope config, but only for this property path.
[{includeKey: false}, 'users', '$id']
would return the users document, but without the non-enumerable
$key
field included.
Available operations
Several firestore functions are made available.
Document
set
,update
anddelete
are made available as non-enumerable methods on each document ($set
,$update
and$delete
respectively).this.todos[completedID].$update({ completed: true });
would mark a todo as completed.
Document property
Document properties can be used directly with
v-model
, which will trigger$update
when changed. This can also be set programmatically.<q-input v-model.lazy="user.bio">
changeName(newName) { this.user.name = newName; }
Note that this functionality is not debounced - to reduce the number of writes you perform, you may add debouncing functionality yourself.
You may also use v-model directly with documents - both documents retrieved directly and those accessed through collections.
computedFirestore(){ user: ['users', '$id']; }, methods: { setUser(name, age, bio){ this.user = { name, age, bio }; }, },
computedFirestore(){ users: ['users'], }, methods: { updateUser(id, newUserDocument){ this.users[id] = newUserDocument; }, },
Attempting to set a document which doesn't exist will create a new document.
Collection
add
is made available as a non-enumerable method$add
on each collection (but not on queries or collections that have been ordered or limited)this.todos.$add({ completed: false, text: newTodoText, due: newTodoDueTimestamp });
would add a new todo
Handlers
Handlers are added as subkeys of the option key handlers
. If you pass a single handler to a hook, all previous (higher) handlers for that hook are removed for any descendant configs. If you pass an array (even just an array with one handler), all previous higher handlers will still be invoked. The available hooks are:
error
Called whenever there is a firebase error. Receives the error as a parameter.once
Called on the first snapshot event after componentcreated
lifecycle hook.populated
Called when all properties have received their first snapshot event after componentcreated
lifecycle hook. Can only be registered at the install or component level.added
Called whenever a document is added. Receives the new document(s) as a parameter. Only valid for collection-type bindings.removed
Called whenever a document is deleted. Recieves an array containing the ID's of the deleted documents. Only valid for collection-type bindings.modified
Called whenever a document is modified. Receives the new document(s) as a parameter.updated
Called whenever one of the previous three would be called. Receives the relevant document(s) as a parameter.changed
Called whenever the document or query ref changes - meaning this runs whenever one of the reactive variables you're depending on changes. Receives the relevant documents as a parameter.
All of the above callbacks, when passing multiple documents (including collections or queries with only one document), will pass either an Object or Array depending on the value of config.collectionsAsObject
.