{"id":17004836,"url":"https://github.com/clickermonkey/vue-fiery","last_synced_at":"2026-04-18T15:40:07.853Z","repository":{"id":152212255,"uuid":"144824992","full_name":"ClickerMonkey/vue-fiery","owner":"ClickerMonkey","description":"The most extensive Google Firestore plugin for Vue","archived":false,"fork":false,"pushed_at":"2018-08-25T03:09:56.000Z","size":190,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-24T14:40:44.360Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ClickerMonkey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-15T08:11:32.000Z","updated_at":"2018-08-27T12:11:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"cd0707eb-ea5c-443c-a9c8-e5a39ce3a345","html_url":"https://github.com/ClickerMonkey/vue-fiery","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ClickerMonkey/vue-fiery","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClickerMonkey%2Fvue-fiery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClickerMonkey%2Fvue-fiery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClickerMonkey%2Fvue-fiery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClickerMonkey%2Fvue-fiery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ClickerMonkey","download_url":"https://codeload.github.com/ClickerMonkey/vue-fiery/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClickerMonkey%2Fvue-fiery/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31974951,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T04:44:35.233Z","updated_at":"2026-04-18T15:40:07.834Z","avatar_url":"https://github.com/ClickerMonkey.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\r\n\u003cp align=\"center\"\u003e\r\n\u003cimg src=\"https://img.shields.io/npm/v/vue-fiery.svg\"\u003e\r\n\u003cimg src=\"https://img.shields.io/npm/l/vue-fiery.svg\"\u003e\r\n\u003cimg src=\"https://travis-ci.org/ClickerMonkey/vue-fiery.svg?branch=master\"\u003e\r\n\u003c/p\u003e\r\n\r\n# This project has been moved [here](https://github.com/fiery-data/fiery-vue)\r\n\r\n## vue-fiery\r\n\r\nVue.js binding for Google Firebase Cloud Firestore.\r\n\r\n#### Features\r\n- Documents [example](#documents)\r\n- Collections (stored as array or map) [example](#collections)\r\n- Queries (stored as array or map) [example](#queries)\r\n- Real-time or once [example](#real-time-or-once)\r\n- Data or computed properties [example](#data-or-computed)\r\n- Adding, updating, sync, removing, remove field [example](#adding-updating-overwriting-removing)\r\n- Sub-collections (with cascading deletions!) [example](#sub-collections)\r\n- Return instances of a class [example](#return-instances-of-a-class)\r\n- Add active record methods (sync, update, remove, clear, getChanges) [example](#active-record)\r\n- Control over what properties are sent on save [example](#save-fields)\r\n- Encode \u0026 decode properties [example](#encode--decode-properties)\r\n- Adding the key to the document [example](#adding-key-to-object)\r\n- Sharing, extending, defining, and global options [example](#sharing-extending-defining-and-global-options)\r\n- Callbacks (error, success, missing, remove) [example](#callbacks)\r\n- Custom binding / unbinding\r\n\r\n**Contents**\r\n- [Dependencies](#dependencies)\r\n- [Installation](#installation)\r\n- [Usage](#usage)\r\n\r\n### Dependencies\r\n\r\n- Firebase ^5.0.0\r\n- Vue: ^1.0.28\r\n\r\n### Installation\r\n\r\n#### npm\r\n\r\nInstallation via npm : `npm install vue-fiery --save`\r\n\r\n### Usage\r\n\r\n```javascript\r\nimport Vue from 'vue'\r\nimport VueFiery from 'vue-fiery'\r\nimport firebase from 'firebase'\r\n\r\nrequire('firebase/firestore')\r\n\r\nVue.use(VueFiery)\r\n\r\nconst firebaseApp = firebase.initializeApp({ ... })\r\nconst db = firebaseApp.firestore();\r\n\r\nvar vm = new Vue({\r\n  el: '#app',\r\n  data() {\r\n    return {\r\n      todos: this.$fiery(db.collection('todos')) // live collection,\r\n      ford: this.$fiery(db.collection('cars').doc('ford')), // live document\r\n      role: 'admin'\r\n    }\r\n  },\r\n  computed: {\r\n    // Updated when role changes\r\n    personsWithRole() {\r\n      return this.$fiery(db.collection('persons'), {\r\n        query: (q) =\u003e q.where('role', '==', this.role),\r\n        type: Person\r\n      })\r\n    }\r\n  }\r\n})\r\n```\r\n\r\nEach record of the array will contain a `.uid` property. This helps identify\r\nwhat firestore database the document is stored, in what collection, and with which options\r\n\r\n```json\r\n[\r\n    {\r\n        \".uid\": \"1///1///todos/-Jtjl482BaXBCI7brMT8\",\r\n        \"name\": \"Star vue-fiery\",\r\n        \"done\": true\r\n    }\r\n]\r\n```\r\n\r\n### Documents\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  inject: ['currentUserId'],\r\n  data() {\r\n    const $fiery = this.$fiery\r\n    return {\r\n      settings: $fiery(db.collection('settings').doc('system')),\r\n      currentUser: $fiery(db.collection('users').doc(this.currentUserId)) // not reactive, but is updated real-time\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Collections\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  data() {\r\n    const $fiery = this.$fiery\r\n    return {\r\n      cars: $fiery(db.collection('cars')) // real-time array\r\n      carMap: $fiery(db.collection('cars'), {map: true}) // real-time map: carMap[id] = car\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Queries\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  inject: ['currentUserId'],\r\n  data() {\r\n    const $fiery = this.$fiery\r\n    return {\r\n      currentCars: $fiery(db.collection('cars'), { // real-time array\r\n        query: (cars) =\u003e cars.where('created_by', '==', this.currentUserId)\r\n      })\r\n      currentCarMap: $fiery(db.collection('cars'), { // real-time map: currentCarMap[id] = car\r\n        query: (cars) =\u003e cars.where('created_by', '==', this.currentUserId),\r\n        map: true\r\n      })\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Real-time or once\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  inject: ['currentUserId'],\r\n  data() {\r\n    const $fiery = this.$fiery\r\n    return {\r\n      // real-time is default, all you need to do is specify once: true to disable it\r\n      cars: $fiery(db.collection('cars'), {once: true}), // array populated once\r\n      currentUser: $fiery(db.collection('users').doc(this.currentUserId), {once: true}), // current user populated once\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Data or computed\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  inject: ['currentUserId'],\r\n  data() {\r\n    // data examples above\r\n    return {\r\n      limit: 25,\r\n      status: 'unfinished'\r\n    }\r\n  },\r\n  computed: {\r\n    currentUser() {\r\n      return this.$fiery(db.collection('users').doc(this.currentUserId)) // reactive and real-time\r\n    },\r\n    todos() {\r\n      return this.$fiery(db.collection('todos'), { // reactive and real-time\r\n        query: (todos) =\u003e todos\r\n          .where('created_by', '==', this.currentUserId)\r\n          .where('status', '==', this.status)\r\n          .limit(this.limit),\r\n\r\n      })\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Adding, updating, overwriting, removing\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  inject: ['currentUserId'],\r\n  data() {\r\n    return {\r\n      todos: this.$fiery(db.collection('todos'))\r\n    }\r\n  },\r\n  computed: {\r\n    currentUser() {\r\n      return this.$fiery(db.collection('users').doc(this.currentUserId))\r\n    }\r\n  },\r\n  methods: {\r\n    addTodo() { // COLLECTIONS STORED IN $fires\r\n      // once successful, this.todos will be updated\r\n      this.$fires.todos.add({\r\n        name: 'Like vue-fiery',\r\n        done: true\r\n      })\r\n    },\r\n    updateUser() {\r\n      this.$fiery.update(this.currentUser)\r\n    },\r\n    updateUserEmailOnly() {\r\n      this.$fiery.update(this.currentUser, ['email'])\r\n    },\r\n    updateAny(data) { // any document can be passed, ex: this.todos[1], this.currentUser\r\n      this.$fiery.update(data)\r\n    },\r\n    overwrite(data) { // only fields present on data will exist on sync\r\n      this.$fiery.sync(data)\r\n    },\r\n    remove(data) {\r\n      this.$fiery.remove(data) // removes sub collections as well\r\n      this.$fiery.remove(data, true) // preserves sub collections\r\n    },\r\n    removeName(todo) {\r\n      this.$fiery.clear(data, 'name') // can also specify an array of props or sub collections\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Sub-collections\r\n\r\nYou can pass the same options to sub, nesting as deep as you want!\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  data() {\r\n    return {\r\n      // this.todos[todoIndex].children[childIndex]\r\n      todos: this.$fiery(db.collection('todos'), {\r\n        sub: {\r\n          children: { // creates an array or map on each todo object: todo.children[]\r\n            // once, map, etc\r\n            query: (children) =\u003e children.orderBy('updated_at')\r\n          }\r\n        }\r\n      })\r\n    }\r\n  },\r\n  methods: {\r\n    addChild(parent) {\r\n      // or this.$fiery.ref(parent, 'children') for short\r\n      this.$fiery.ref(parent).collection('children').add({\r\n        name: 'Fork vue-fiery',\r\n        done: false\r\n      })\r\n    },\r\n    clearChildren(parent) {\r\n      this.$fiery.clear(parent, 'children') // clear the sub collection\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Return instances of a class\r\n\r\n```javascript\r\nfunction Todo() {\r\n\r\n}\r\nTodo.prototype = {\r\n  markDone (byUser) {\r\n    this.done = true\r\n    this.updated_at = Date.now()\r\n    this.updated_by = byUser.id\r\n  }\r\n}\r\n\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  data() {\r\n    return {\r\n      // this.todos[todoIndex] instanceof Todo\r\n      todos: this.$fiery(db.collection('todos'), {\r\n        type: Todo,\r\n        // OR you can specify newDocument and do custom loading (good for polymorphic data)\r\n        newDocument: function(initialData) {\r\n          var instance = new Todo()\r\n          instance.callSomeMethod()\r\n          return instance\r\n        }\r\n      })\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Active Record\r\n\r\n```javascript\r\n// can be used with type, doesn't have to be\r\nfunction Todo() {\r\n\r\n}\r\nTodo.prototype = {\r\n  markDone (byUser) {\r\n    this.done = true\r\n    this.updated_at = Date.now()\r\n    this.updated_by = byUser.id\r\n    this.$update()\r\n  }\r\n}\r\n\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  data() {\r\n    return {\r\n      todos: this.$fiery(db.collection('todos'), {\r\n        type: Todo,\r\n        record: true\r\n        // $sync, $update, $remove, $ref, $clear, $getChanges are functions added to every Todo instance\r\n      }),\r\n      todosCustom: this.$fiery(db.collection('todos'), {\r\n        record: true,\r\n        recordOptions: { // which methods do you want added to every object, and with what method names?\r\n          sync: 'sync',\r\n          update: 'save',\r\n          remove: 'destroy'\r\n          // we don't want $ref, $clear, or $getChanges\r\n        }\r\n      })\r\n    }\r\n  },\r\n  methods: {\r\n    updateTodoAt(index) {\r\n      // instead of this.$fiery.update(this.todos[index])\r\n      this.todos[index].$update()\r\n    },\r\n    saveTodoCustomAt(index) {\r\n      // instead of this.$fiery.update(this.todosCustom[index])\r\n      this.todosCustom[index].save()\r\n    },\r\n    done(todo) {\r\n      todo.markDone(this.currentUser) // assuming currentUser exists\r\n    },\r\n    getChanges(todo) {\r\n      todo.$getChanges(['name', 'done'], function(changes, saved, current) {\r\n        // are there unsaved changes in name or done? (exclude array to check entire document)\r\n      })\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Save fields\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  data() {\r\n    return {\r\n      todos: this.$fiery(db.collection('todos'), {\r\n        include: ['name', 'done'], // if specified, we ONLY send these fields on sync/update\r\n        exclude: ['hidden'] // if specified here, will not be sent on sync/update\r\n      }),\r\n    }\r\n  },\r\n  methods: {\r\n    save(todo) {\r\n      this.$fiery.update(todo)\r\n    },\r\n    saveDone(todo) {\r\n      this.$fiery.update(todo, ['done']) // only send this value if it exists\r\n    },\r\n    saveOverride(todo) {\r\n      this.$fiery.update(todo, ['hidden']) // ignores exclude and include when specified\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Encode \u0026 decode properties\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  data() {\r\n    return {\r\n      todos: this.$fiery(db.collection('todos'), {\r\n        // convert server values to local values\r\n        decoders: {\r\n          status(remoteValue, remoteData) {\r\n            return remoteValue === 1 ? 'done' : (remoteValue === 2 ? 'started' : 'not started')\r\n          }\r\n        },\r\n        // convert local values to server values\r\n        encoders: {\r\n          status(localValue, localData) {\r\n            return localValue === 'done' ? 1 : (localeValue === 'started' ? 2 : 0)\r\n          }\r\n        },\r\n        // optionally instead of individual decoders you can specify a function\r\n        decode(remoteData) {\r\n          // do some decoding, maybe do something special\r\n          return remoteData\r\n        }\r\n      })\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Adding key to object\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  data() {\r\n    return {\r\n      todos: this.$fiery(db.collection('todos'), {key: 'id', exclude: ['id']}) // must be excluded manually\r\n    }\r\n  },\r\n  methods: {\r\n    log(todo) {\r\n      // todo.id exists now\r\n      console.log(todo)\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Sharing, extending, defining, and global options\r\n\r\n```javascript\r\n// ==== Sharing ====\r\nlet Todo = {\r\n  shared: true, // necessary for non-global or defined options that are used multiple times\r\n  include: ['name', 'done', 'done_at']\r\n}\r\n\r\n// ==== Extending ====\r\nlet TodoWithChildren = {\r\n  shared: true\r\n  extends: Todo,\r\n  sub: {\r\n    children: Todo\r\n  }\r\n}\r\n\r\n// ==== Defining ====\r\nVueFiery.define('post', {\r\n  // shared is not necessary here\r\n  include: ['title', 'content', 'tags']\r\n})\r\n\r\n// or multiple\r\nVueFiery.define({\r\n  comment: {\r\n    include: ['author', 'content', 'posted_at', 'status'],\r\n    sub: {\r\n      replies: 'comment' // we can reference options by name now, even circularly\r\n    }\r\n  },\r\n  images: {\r\n    include: ['url', 'tags', 'updated_at', 'title']\r\n  }\r\n})\r\n\r\n// ==== Global ====\r\nVueFiery.setGlobalOptions({\r\n  // lets make everything active record\r\n  record: true,\r\n  recordOptions: {\r\n    update: 'save',         // object.save(fields?)\r\n    sync: 'sync',           // object.sync(fields?)\r\n    remove: 'remove',       // object.remove()\r\n    clear: 'clear',         // object.clear(fields)\r\n    ref: 'doc',             // object.doc().collection('subcollection')\r\n    getChanges: 'changes'   // object.changes((changes, remote, local) =\u003e {})\r\n  }\r\n})\r\n\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  data() {\r\n    return {\r\n      comments: this.$fiery(db.collection('comment'), 'comment') // you can pass a named or Shared\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n### Callbacks\r\n\r\n```javascript\r\nconst db = firebaseApp.firestore();\r\nnew Vue({\r\n  data() {\r\n    return {\r\n      todos: this.$fiery(db.collection('todos'), {\r\n        onSuccess: (todos) =\u003e {},\r\n        onError: (message) =\u003e {},\r\n        onRemove: () =\u003e {},\r\n        onMissing: () =\u003e {} // occurs for documents\r\n      })\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n## LICENSE\r\n[MIT](https://opensource.org/licenses/MIT)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclickermonkey%2Fvue-fiery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclickermonkey%2Fvue-fiery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclickermonkey%2Fvue-fiery/lists"}