A Firebase-Style Database ... Offline! originally made by dannyconnell
Localbase gives you an offline database with the simplicity & power of Firebase, all stored in the user's browser (in an IndexedDB database).
You can create as many databases as you like.
Databases are organised into Collections and Documents (just like Firebase Cloud Firestore).
- Databases contain Collections (e.g.
users
) - Collections contain Documents (e.g.
{ id: 1, name: 'Bill', age: 47 }
Localbase is built on top of LocalForage.
- Getting Started
- Video Introduction
- Quick Start
- Adding Data
- Getting Data
- Deleting Data
- Advanced Usage with Keys
- Promises
- Async / Await
- Configuration
- Localbase Playground
<script src="https://unpkg.com/localbase/dist/localbase.dev.js"></script>
<script>
let db = new Localbase('db')
</script>
Or, use the minified, production version:
<script src="https://unpkg.com/localbase/dist/localbase.min.js"></script>
<script>
let db = new Localbase('db')
</script>
npm install localbase --save
import Localbase from 'localbase'
let db = new Localbase('db')
npm install localbase
// plugins/localbase.js
import Localbase from 'localbase'
let db = new Localbase('db')
export default (context,inject) => {
inject('db', db)
}
// nuxt.config.js
export default {
...
plugins: [
{ src: "~/plugins/localbase", mode: "client" }
],
...
}
<!-- pages/index.vue -->
<script>
export default {
head: {
title: 'Nuxt Blog - Home'
},
mounted() {
this.$db.collection('users').add({
id: 1,
name: 'Bill',
age: 47
})
}
}
</script>
Watch my Video Introduction to Localbase, including how to get started:
Get started by adding a document to a collection. Just specify the collection name with the collection
method (the collection will be created automatically) then specify the document you want to add with the add
method:
db.collection('users').add({
id: 1,
name: 'Bill',
age: 47
})
Simples!
Once you've added some data to a collection, you can get the whole collection with the get
method:
db.collection('users').get().then(users => {
console.log(users)
})
// [
// { id: 1, name: 'Bill', age: 47 },
// { id: 2, name: 'Paul', age: 34 }
// ]
Add a new document to a collection.
db.collection('users').add({
id: 1,
name: 'Bill',
age: 47
})
Update an existing document. Just pass an object with a field and value (usually id) to match the document. Then pass in only the fields you want to update with the update
method.
db.collection('users').doc({ id: 1 }).update({
name: 'William'
})
// [
// { id: 1, name: 'William', age: 47 },
// { id: 2, name: 'Paul', age: 34 }
// ]
Note: if more than one document is matched by your criteria e.g .doc({ gender: 'male' })
then all matched documents will be updated.
Overwrite an existing document. This will completely overwrite the selected document, so all required fields should be passed into the set
method.
db.collection('users').doc({ id: 2 }).set({
id: 4,
name: 'Pauline',
age: 27
})
// [
// { id: 1, name: 'William', age: 47 },
// { id: 4, name: 'Pauline', age: 27 }
// ]
Note: if more than one document is matched by your criteria e.g .doc({ gender: 'male' })
then all matched documents will be overwritten.
Overwrite an entire collection with an array of documents. This will completely overwrite the selected collection.
db.collection('users')
.set([
{
id: 1,
name: 'Bill',
age: 48
},
{
id: 2,
name: 'Paul',
age: 28
}
])
// [
// { id: 1, name: 'Bill', age: 48 },
// { id: 2, name: 'Paul', age: 28 }
// ]
Get all items from a collection. The collection will be returned in an array.
db.collection('users').get().then(users => {
console.log(users)
})
// [
// { id: 1, name: 'Bill', age: 47 },
// { id: 2, name: 'Paul', age: 34 }
// ]
Get a collection and order it by a particular field (ascending).
db.collection('users').orderBy('age').get().then(users => {
console.log('users: ', users)
})
// [
// { id: 2, name: 'Paul', age: 34 },
// { id: 1, name: 'Bill', age: 47 }
// ]
Get a collection and order it by a particular field (descending).
db.collection('users').orderBy('name', 'desc').get().then(users => {
console.log('users: ', users)
})
// [
// { id: 2, name: 'Paul', age: 34 },
// { id: 1, name: 'Bill', age: 47 }
// ]
Order a collection & limit it to a particular number of documents.
db.collection('users').orderBy('name', 'desc').limit(1).get().then(users => {
console.log('users: ', users)
})
// [
// { id: 2, name: 'Paul', age: 34 }
// ]
Get an individual document from a collection
db.collection('users').doc({ id: 1 }).get().then(document => {
console.log(document)
})
// { id: 1, name: 'Bill', age: 47 }
Delete a document from a collection.
db.collection('users').doc({ id: 1 }).delete()
// [
// { id: 2, name: 'Paul', age: 34 }
// ]
Note: if more than one document is matched by your criteria e.g .doc({ gender: 'male' })
then all matched documents will be deleted.
Delete a collection and all documents contained in it.
db.collection('users').delete()
Delete a database and all collections contained in it.
db.delete()
Your documents are stored in an IndexedDB store with keys:
By default, Localbase generates random, ordered, unique IDs for these keys.
But you might want to take control of these keys. For example, you might want to:
- Specify your own key when you add a document
- Use the key for selecting a document (when getting, updating, setting or deleting a document) instead of using some document criteria
- Return all of the keys as well as the document fields, when getting a collection, e.g.
[
{
key: 'mykey-2',
data: {
{ id: 2, name: 'Paul', age: 34 }
}
},
{
key: 'mykey-1',
data: {
{ id: 1, name: 'Bill', age: 47 }
}
}
]
You can do all this with Localbase:
After specifying your document data, pass in a key (to be used by the IndexedDB store) as a second parameter:
db.collection('users').add({
id: 1,
name: 'Bill',
age: 47
}, 'mykey-1')
Or, you can just use the set
method:
db.collection('users').doc('mykey-1').set({
id: 1,
name: 'Bill',
age: 47
})
Which would look like this in the IndexedDB:
Overwrite an entire collection with an array of documents, and specify a key for each document. Make sure you pass in the { keys: true }
option. This will completely overwrite the selected collection.
db.collection('users')
.set([
{
id: 1,
name: 'Bill',
age: 48,
_key: 'mykey-1'
},
{
id: 2,
name: 'Paul',
age: 28,
_key: 'mykey-2'
}
], { keys: true })
When selecting a document with the doc
method, instead of passing in an object with a field name and value, just pass in a string (or integer) with your key:
// get document by key
db.collection('users').doc('mykey-1').get().then(document => {
console.log(document)
})
// update document by key
db.collection('users').doc('mykey-1').update({
name: 'William'
})
// set document by key
db.collection('users').doc('mykey-2').set({
id: 4,
name: 'Pauline',
age: 27
})
// delete a document by key
db.collection('users').doc('mykey-1').delete()
When getting a collection, just pass { keys: true }
into the get
method:
db.collection('users').orderBy('name', 'desc').get({ keys: true }).then(users => {
console.log('users: ', users)
})
// [
// {
// key: 'mykey-2',
// data: {
// { id: 2, name: 'Paul', age: 34 }
// }
// },
// {
// key: 'mykey-1',
// data: {
// { id: 1, name: 'Bill', age: 47 }
// }
// }
// ]
You can add promises to all operations and do something when it's successful, or when there's an error.
db.collection('users')
.add({
id: 1,
name: 'Bill',
age: 47
}, 'mykey-1')
.then(response => {
console.log('Add successful, now do something.')
})
.catch(error => {
console.log('There was an error, do something else.')
})
// you can test the error by passing a
// string, number or boolean into the
// .add() method, instead of an object
db.collection('users')
.doc({ id: 1 })
.update({
name: 'William'
})
.then(response => {
console.log('Update successful, now do something.')
})
.catch(error => {
console.log('There was an error, do something else.')
})
// you can test the error by passing nothing
// into the update() method
db.collection('users')
.doc({ id: 1 })
.set({
id: 1,
name: 'Pauline',
age: 27
})
.then(response => {
console.log('Set successful, now do something.')
})
.catch(error => {
console.log('There was an error, do something else.')
})
// you can test the error by passing nothing
// into the set() method
db.collection('users')
.doc({ id: 1 })
.delete()
.then(response => {
console.log('Delete successful, now do something.')
})
.catch(error => {
console.log('There was an error, do something else.')
})
// you can test the error by passing nothing
// into the doc() method
db.collection('users')
.delete()
.then(response => {
console.log('Collection deleted, now do something.')
})
.catch(error => {
console.log('There was an error, do something else')
})
// you can test the error by passing nothing
// into the collection() method
db.delete()
.then(response => {
console.log('Database deleted, now do something.')
})
.catch(error => {
console.log('There was an error, do something else.')
})
// note: sometimes when you delete a
// database, the change won't show up
// in Chrome Dev tools til you reload
// the page
You can also use Async / Await with all operations
async function addUsers() {
await db.collection('users').add({
id: 1,
name: 'Bill',
age: 47
})
console.log('first user added')
await db.collection('users').add({
id: 2,
name: 'Paul',
age: 34
})
console.log('second user added')
}
addUsers()
async function updateUser() {
let result = await db.collection('users')
.doc({ id: 1 })
.update({
name: 'William'
})
console.log(result)
}
updateUser()
async function setUser() {
let result = await db.collection('users')
.doc({ id: 2 })
.set({
id: 4,
name: 'Pauline',
age: 27
})
console.log(result)
}
setUser()
async function getUsers() {
try {
let users = await db.collection('users')
.orderBy('age')
.get()
console.log('users: ', users)
}
catch(error) {
console.log('error: ', error)
}
}
getUsers()
// test the error by passing nothing into collection()
By default, when in development, Localbase will fire out gorgeously labelled debug logs like this:
You can disable these logs by setting db.config.debug
to false
.
It's best to do this after you initialize the database, and before you do anything else:
import Localbase from 'localbase'
let db = new Localbase('db')
db.config.debug = false
// now do some stuff with the motherflipping db yo
Localbase Playground is an app for playing around with Localbase and all the available methods.
It contains a bunch of different code snippets (for adding, updating, setting and getting) data to/from a Localbase database.
You can launch these code snippets (and edit them if you like) in the browser and observe the result in the IndexedDB database and in the console.