vue-computed-firestore v0.3.2
vue-computed-firestore
Simple two-way(ish) binding of firestore docs and collections to vue computed properties.
Install
npm install vue-computed-firestoreUsage
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
$configwithin thecomputedFirestore()return object - As an object at index 0 within a property path array
Available options
firebaseRoot 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 theidof 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 = trueWhether 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
orderByandlimitkeys.limitmust be a number (or link to a reactive property which is a number), whileorderBycan 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.$numberToShowuncompleted 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
$keyfield included.
Available operations
Several firestore functions are made available.
Document
set,updateanddeleteare made available as non-enumerable methods on each document ($set,$updateand$deleterespectively).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$updatewhen 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
addis made available as a non-enumerable method$addon 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:
errorCalled whenever there is a firebase error. Receives the error as a parameter.onceCalled on the first snapshot event after componentcreatedlifecycle hook.populatedCalled when all properties have received their first snapshot event after componentcreatedlifecycle hook. Can only be registered at the install or component level.addedCalled whenever a document is added. Receives the new document(s) as a parameter. Only valid for collection-type bindings.removedCalled whenever a document is deleted. Recieves an array containing the ID's of the deleted documents. Only valid for collection-type bindings.modifiedCalled whenever a document is modified. Receives the new document(s) as a parameter.updatedCalled whenever one of the previous three would be called. Receives the relevant document(s) as a parameter.changedCalled 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.