{"id":22040336,"url":"https://github.com/inventsable/leylo","last_synced_at":"2025-07-23T04:35:55.910Z","repository":{"id":53408364,"uuid":"195326811","full_name":"Inventsable/leylo","owner":"Inventsable","description":"Asynchronous utility functions for Firestore within Vue CLI 3","archived":false,"fork":false,"pushed_at":"2021-03-30T23:37:36.000Z","size":170,"stargazers_count":4,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-12T17:02:35.123Z","etag":null,"topics":["firebase","firestore","vue","vuejs"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Inventsable.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-05T02:37:27.000Z","updated_at":"2023-10-02T06:52:28.000Z","dependencies_parsed_at":"2022-08-27T19:00:45.564Z","dependency_job_id":null,"html_url":"https://github.com/Inventsable/leylo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Inventsable/leylo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Inventsable%2Fleylo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Inventsable%2Fleylo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Inventsable%2Fleylo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Inventsable%2Fleylo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Inventsable","download_url":"https://codeload.github.com/Inventsable/leylo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Inventsable%2Fleylo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266618971,"owners_count":23957273,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"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":["firebase","firestore","vue","vuejs"],"created_at":"2024-11-30T11:14:06.124Z","updated_at":"2025-07-23T04:35:55.882Z","avatar_url":"https://github.com/Inventsable.png","language":"JavaScript","readme":"# leylo [![npm version](https://badge.fury.io/js/leylo.svg)](https://badge.fury.io/js/leylo) [![npm](https://img.shields.io/npm/dm/leylo.svg)]()\n\n[![NPM](https://nodei.co/npm/leylo.png)](https://nodei.co/npm/leylo/)\n\n| [Installation](#-installation) | [Requirements](#-requirements) | [Usage](#-usage) | [Demo](https://github.com/Inventsable/leylo-test) | [📚 API](#-api) |\n| ------------------------------ | :----------------------------: | :--------------: | :-----------------------------------------------: | :-------------: |\n\n\nAsynchronous utility functions for [Firestore](https://firebase.google.com/docs/firestore/quickstart) within [Vue CLI 3](https://cli.vuejs.org/).\n\n#### See a [demo site here](https://leylo-test.web.app/) with [source code here](https://github.com/Inventsable/leylo-test)\n\n## ▸ Installation\n\n```bash\nnpm install leylo\n```\n\nIf not using Firebase Hosting, there's no need to `npm install firebase` or `npm install firebase-tools`. Just plug in the credentials within your `.env` and you're good to go!\n\n---\n\n## ▸ Requirements\n\nYou must have a `.env` file at the root of your Vue CLI 3 repo containing the following key/value pairs ([template available in this repo](https://github.com/Inventsable/leylo/blob/master/.env)):\n\n```env\nVUE_APP_FIREBASE_APIKEY=...\nVUE_APP_FIREBASE_AUTHDOMAIN=...\nVUE_APP_FIREBASE_DATABASEURL=...\nVUE_APP_FIREBASE_PROJECTID=...\nVUE_APP_FIREBASE_STORAGEBUCKET=...\nVUE_APP_FIREBASE_MESSAGINGSENDERID=...\nVUE_APP_FIREBASE_APPID=...\n```\n\nNo quotation marks needed in `.env` values above\n\n![](./assets/anno.png)\n\n---\n\n## ▸ Usage\n\n```html\n\u003cscript\u003e\n  // Within a .vue file\n  import leylo from \"leylo\";\n\n  export default {\n    name: \"yourComponent\",\n    // If using async/await, must define mounted/created/function as async\n    async mounted() {\n      let validation = await leylo.docExists(\"users\", \"Inventsable\");\n      console.log(validation); //  Returns true\n\n      // All functions are thenable if not using async\n      leylo.getDocById(\"users\", \"Inventsable\").then(response =\u003e {\n        console.log(response); //  Returns { name: 'Tom Scharstein', ... }\n      });\n    }\n  };\n\u003c/script\u003e\n```\n\n---\n\n## 📚 API\n\nAll methods are accessible as properties of `leylo`, as in `leylo.docExists(...)`.\n\n\u003cspan style=\"font-size: 1.25rem; font-weight: 500;\"\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;📗 [Global](#--global)\u003cspan\u003e\u003cbr\u003e\n\u003cspan style=\"font-size: 1.25rem; font-weight: 500;\"\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;📙 [Retrieving Data](#--retreiving-data)\u003cspan\u003e\u003cbr\u003e\n\u003cspan style=\"font-size: 1.25rem; font-weight: 500;\"\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;📘 [Adding Data](#--adding-data)\u003cspan\u003e\u003cbr\u003e\n\u003cspan style=\"font-size: 1.25rem; font-weight: 500;\"\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;📕 [Deleting Data](#--deleting-data)\u003cspan\u003e\u003cbr\u003e\n\n## \u0026nbsp;\u0026nbsp;[◤](#-api)\u0026nbsp;\u0026nbsp; 📗 Global\n\n\u003e [◤](#-api)\u0026nbsp;\u0026nbsp; Click these arrows to return to the top of the API\n\n### \u0026nbsp;\u0026nbsp; `.db`\n\nReturns `Object` of interior `Firestore` used for all queries.\n\n```js\nconsole.log(leylo.db);\n// Returns Firestore {_queue: AsyncQueue, INTERNAL: {…}, _config: FirestoreConfig, _databaseId: DatabaseId, _dataConverter: UserDataConverter, …}\n```\n\nCan be used as an alias to any custom `Firestore` [query](https://googleapis.dev/nodejs/firestore/latest/Query.html) or method:\n\n```js\nlet query = leylo.db.collection(\"col\");\n\nquery\n  .orderBy(\"foo\")\n  .endAt(42)\n  .get()\n  .then(querySnapshot =\u003e {\n    querySnapshot.forEach(documentSnapshot =\u003e {\n      console.log(`Found document at ${documentSnapshot.ref.path}`);\n    });\n  });\n```\n\n---\n\n\u003c!-- \u003cspan style=\"float: right\"\u003e[Back to API 2](#api)\u003c/span\u003e --\u003e\n\n## \u0026nbsp;\u0026nbsp;[◤](#-api)\u0026nbsp;\u0026nbsp; 📙 Retreiving Data\n\n- [leylo.docExists()](#-docexistscollection-id)\n- [leylo.collectionExists()](#-collectionexistscollection)\n- [leylo.getPath()](#-getpathpath-getdata)\n- [leylo.getCollection()](#-getcollectioncollection-getdata)\n- [leylo.getDocById()](#-getdocbyidcollection-id-getdata)\n- [leylo.getDocByField()](#-getdocbyfieldcollection-field-value-getdata)\n- [leylo.getDocByQuery()](#-getdocbyquerycollection-field-query-value-getdata)\n- [leylo.getAllDocsByField()](#-getalldocsbyfieldcollection-field-value-getdata)\n- [leylo.getAllDocsByQuery()](#-getalldocsbyquerycollection-field-query-value-getdata)\n- [leylo.getDocIdByField()](#-getdocidbyfieldcollection-field-value)\n- [leylo.getDocPathByField()](#-getdocPathbyfieldcollection-field-value)\n- [leylo.streamCollection()](#-streamcollectioncollection-callback-changetype-getdata)\n- [leylo.streamPath()](#-streampathpath-callback-changetype-getdata)\n- [leylo.streamDocChangesById()](#-streamdocchangesbyidcollection-id-callback-getdata)\n- [leylo.streamDocChangesByField()](#-streamdocchangesbyfieldcollection-field-value-callback-changetype-getdata)\n- [leylo.streamDocChangesByQuery()](#-streamdocchangesbyquerycollection-field-query-value-callback-changetype-getdata)\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.docExists(collection, id)`\n\n\u003e \u0026nbsp;\u0026nbsp;[▲](#--global)\u0026nbsp;\u0026nbsp; Click these arrows to return to the top of each segment\n\nReturns `Boolean` of whether document with specified `id` is found in Firestore\n\n- `collection` **[String]** - Name of collection\n- `id` **[String]** - Name/ID of document within collection\n\n```js\n// WITHIN ASYNC FUNCTION\nlet validation = await leylo.docExists(\"users\", \"Inventsable\");\nconsole.log(validation); //  Returns true\n\n// OR THENABLE\nleylo.docExists(\"users\", \"Inventsable\").then(response =\u003e {\n  console.log(response); // Returns true\n});\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.collectionExists(collection)`\n\nReturns `Boolean` of whether collection with specified name is found in Firestore\n\n- `collection` **[String]** - Name of collection\n\n```js\nlet validation = await leylo.collectionExists(\"users\");\nconsole.log(validation); //  Returns true\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.getPath(path[, getData?])`\n\nReturns `Array` if collection, `Object` if document, or `Any` if field of specified `path` or `False` if not found\n\n- `path` **[String]** - Path in the form collection or collection/document\n- `getData` **[Boolean]** (_Default: true_) - If `true` returns `documentSnapshot.data()` else returns `documentSnapshot`\n\n```js\n// Simple grab all documents within a collection:\nlet userList = await leylo.getPath(\"users\");\nconsole.log(userList); // Returns [{…}, {…}, {…}, {…}, {…}]\n\n// Simple grab single document from specific collection/document path:\nlet certainUser = await leylo.getPath(\"users/Inventsable\");\nconsole.log(userList); // Returns { name: 'Tom Scharstein', ... }\n\n// Simple grab value from specific collection/document/field path:\nlet certainUserLocation = await leylo.getPath(\"users/Inventsable/location\");\nconsole.log(certainUserLocation); // Returns 'Arizona'\n\n// Add all documents to a specified array in component's data\nlet doSomethingEveryUser = await leylo.getPath(\"users\", false);\n\ndoSomethingEveryUser.forEach(user =\u003e {\n  this.userList.push(user.data());\n});\n\n// When adding to pre-existing array, add items which don't already exist in that array:\nlet addUsersAgain = await leylo.getPath(\"users\");\naddUsersAgain.forEach(user =\u003e {\n  // Add item to array if array doesn't contain this same key = value pair\n  // This is similar to Array.includes() and returns Boolean but by targeting Prop of Object within Array\n  if (!this.userList.some(person =\u003e person.fullName == user.fullName))\n    this.userList.push(user);\n  else console.log(`${user.fullName} already existed in this.userList`);\n});\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.getCollection(collection[, getData?])`\n\nReturns `Array` of `Object`s within specified collection or `False` if not found\n\n- `collection` **[String]** - Name of collection\n- `getData` **[Boolean]** (_Default: true_) - If `true` returns `documentSnapshot.data()` else returns `documentSnapshot`\n\n```js\n// Simple grab all documents within a collection:\nlet userList = await leylo.getCollection(\"users\");\nconsole.log(userList); // Returns [{…}, {…}, {…}, {…}, {…}]\n\n// If needing to grab the Document Reference, we can pass false to getData:\nlet doSomethingEveryUser = leylo.getCollection(\"users\", false).then(users =\u003e {\n  users.forEach(user =\u003e {\n    console.log(`${user.id} is at ${user.ref.path} and contains:`); // Inventsable is at userList/Inventsable and contains\n    console.log(user.data()); // Returns Object with document contents { ... }\n  });\n});\n\nlet doSomethingAsyncForList = await leylo.getCollection(\"users\", false);\nconsole.log(\"This prints at the top\");\nPromise.all(\n  doSomethingAsyncEveryUser.map(user =\u003e {\n    console.log(`This prints in the middle: ${user.id}`); // This prints in the middle: Inventsable\n    Promise.resolve(true);\n  })\n);\nconsole.log(`This prints at the bottom`);\n// Now continue to next code\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.getDocById(collection, id[, getData?])`\n\nReturns `Object` with specified `id` in Firestore or `False` if not found\n\n- `collection` **[String]** - Name of collection\n- `id` **[String]** - Name/ID of document within collection\n- `getData` **[Boolean]** (_Default: true_) - If `true` returns `documentSnapshot.data()` else returns `documentSnapshot`\n\n```js\nlet user = await leylo.getDocById(\"users\", \"Inventsable\");\nconsole.log(user); //  Returns { name: 'Tom Scharstein', ... }\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.getDocByField(collection, field, value[, getData?])`\n\nReturns `Object` with specified `field` = `value` in Firestore or `False` if not found\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key/field of target document\n- `value` **[String]** - Value of key/field of target document\n- `getData` **[Boolean]** (_Default: true_) - If `true` returns `documentSnapshot.data()` else returns `documentSnapshot`\n\n```js\nlet user = await leylo.getDocByField(\"users\", \"name\", \"Tom Scharstein\");\nconsole.log(user); //  Returns { name: 'Tom Scharstein', ... }\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.getAllDocsByField(collection, field, value[, getData?])`\n\nReturns `Array` of every `Object` with specified `field` = `value` in collection or `False` if none found\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key/field of target document\n- `value` **[String]** - Value of key/field of target document\n- `getData` **[Boolean]** (_Default: true_) - If `true` returns `documentSnapshot.data()` else returns `documentSnapshot`\n\n```js\nlet usersInArizona = await leylo.getAllDocsByField(\n  \"users\",\n  \"location\",\n  \"Arizona\"\n);\n// Returns [ {...}, {...}, {...} ]\nusersInArizona.forEach(user =\u003e {\n  console.log(user); //  Returns { name: 'Tom', location: 'Arizona', ... }\n});\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.getDocIdByField(collection, field, value)`\n\n\u003e Same as using `await leylo.getDocByField(\"users\", \"name\", \"Tom Scharstein\", false).id`\n\nReturns `String` of specified `field` = `value` document's `id` in collection or `False` if not found\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key/field of target document\n- `value` **[String]** - Value of key/field of target document\n\n```js\n// If we don't know the path to our document, but know a certain key/value pair only it has:\nlet userId = await leylo.getDocIdByField(\"users\", \"name\", \"Tom Scharstein\");\nconsole.log(userId); //  Returns 'Inventsable'\n\n// We can query it to return the Document.id, and know the path must be users/Inventsable\n\nlet checkPath = await leylo.getPath(\"users/Inventsable\");\nconsole.log(checkPath); //  Returns { name: 'Tom Scharstein', location: 'Arizona', ... }\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.getDocPathByField(collection, field, value)`\n\n\u003e Same as using `await leylo.getDocByField(\"users\", \"name\", \"Tom Scharstein\", false).ref.path`\n\nReturns `String` with specified `field` = `value` document's path in Firestore or `False` if not found\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key/field of target document\n- `value` **[String]** - Value of key/field of target document\n\n```js\nlet fullPathToUser = await leylo.getDocPathByField(\n  \"users\",\n  \"name\",\n  \"Tom Scharstein\"\n);\nconsole.log(fullPathToUser); //  Returns 'users/Inventsable'\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.getDocByQuery(collection, field, query, value[, getData?])`\n\nReturns first `Object` found with specified `field` `(query)` `value` in Firestore or `False` if not found\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key/field of target document\n- `query` **[String]** - One of `==`, `\u003e=`, `\u003c=`, `\u003e`, `\u003c`, `array_contains` or valid Firebase query string\n- `value` **[String]** - Value of key/field of target document\n- `getData` **[Boolean]** (_Default: true_) - If `true` returns `documentSnapshot.data()` else returns `documentSnapshot`\n\n```js\n// Grab the first user containing key of temperature less than or equal to 10\nlet userInAlaska = await leylo.getDocByQuery(\"users\", \"temperature\", \"\u003c=\", 10);\n\nconsole.log(userInAlaska); // Returns { name: 'John Doe' }\n\n// Grab the first user where temperature is greator or equal to 10 as DocumentReference\nlet userNotInAlaska = await leylo.getDocByQuery(\n  \"users\",\n  \"temperature\",\n  \"\u003e=\",\n  10,\n  false // Passing false to getData gives us the DocumentReference\n);\n\nconsole.log(userNotInAlaska.ref.path); // Returns 'users/Inventsable'\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.getAllDocsByQuery(collection, field, query, value[, getData?])`\n\nReturns `Array` of every `Object` with specified `field` `(query)` `value` in Firestore or `False` if none found\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key/field of target document\n- `query` **[String]** - One of `==`, `\u003e=`, `\u003c=`, `\u003e`, `\u003c`, `array_contains` or valid Firebase query string\n- `value` **[String]** - Value of key/field of target document\n- `getData` **[Boolean]** (_Default: true_) - If `true` returns `documentSnapshot.data()` else returns `documentSnapshot`\n\n```js\n// Get Array of all documents where temperature field contains value greater or equal to 110\nlet placeTooHotToLiveIn = await leylo.getAllDocsByQuery(\n  \"states\",\n  \"temperature\",\n  \"\u003e=\"\n  110,\n  false\n);\nconsole.log(placesTooHotToLiveIn) //  Returns [ {...}, {...}, {...} ]\n\nplaceTooHotToLiveIn.forEach(place =\u003e {\n  console.log(place);  //  Returns DocumentSnapshot{ ... }\n});\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.streamCollection(collection[, callback, changeType, getData?])`\n\n\u003e Cannot be detached -- if needing programmatic detachment use .streamPath() instead\n\nReturns **every matching** result of passing document `Object` as parameter to `callback` every time the collection is modified. Initial results are same as `this.getCollection()` but reactive and continuous to catch any docs added to this collection later and execute callback on them as well.\n\n- `collection` **[String]** - Name of collection\n- `callback` **[Function]** (_Default: null_) - Function to execute on every change to document. If `null`, returns direct `Object` according to `getData` parameter\n- `changeType` **[String]** (_Default: null_) - If `null` listen to all, else one of `added`, `modified`, or `removed`\n- `getData` **[Boolean]** (_Default: true_) - If `true` passes `querySnapshot.docChanges().data()` to `callback` else passes `querySnapshot.docChanges()`\n\n```js\n// Simple usage:\nlet streamUsers = await leylo.streamCollection(\"users\", res =\u003e {\n  console.log(\"User detected:\");\n  console.log(res); // Returns { name: 'Inventsable', ... }\n});\n\n// From the demo page:\nlet addUserStream = await leylo.streamCollection(\n  \"users\",\n  this.addUserIfNotInList,\n  \"added\"\n);\n\n// Above is the same as:\nlet addUserStream = await leylo.streamCollection(\n  \"users\",\n  user =\u003e {\n    // If this.userList doesn't already contain this user, add it to our component's data:\n    if (!this.userList.some(person =\u003e person.fullName == user.fullName))\n      this.userList.push(user);\n  },\n  \"added\"\n);\n\n// Automatically remove user from this.userList via method:\nasync mounted() {\n  this.startRemoveStream()\n},\nmethods: {\n  async startRemoveStream() {\n    return await leylo.streamCollection(\n      \"users\",\n      user =\u003e {\n        // Easy to update by filtering this.userList to entries not equal to the document just removed:\n        this.userList = this.userList.filter(item =\u003e {\n          return item.fullName !== user.data().fullName;\n        });\n      },\n      \"removed\",\n      // Passing false to getData in case we need the Document.id or see changes\n      false\n    );\n  },\n}\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.streamPath(path[, callback, changeType, getData?])`\n\nReturns `Object` which can be programmatically detached, but still executes `callback` on any document/data.\n\n- `path` **[String]** - Any valid path from `collection` to `collection/document`\n- `callback` **[Function]** (_Default: null_) - Function to execute on every change to document. If `null`, returns direct `Object` according to `getData` parameter\n- `changeType` **[String]** (_Default: null_) - If `null` listen to all, else one of `added`, `modified`, or `removed`\n- `getData` **[Boolean]** (_Default: true_) - If `true` passes `querySnapshot.docChanges().data()` to `callback` else passes `querySnapshot.docChanges()`\n\n```js\n\nasync mounted() {\n  // Starts the stream\n  this.startStream();\n  // The method below results in a `Hello NAME` statement for any user added until the stream is detached.\n\n  setTimeout(() =\u003e {\n    // Stops streaming after 10 seconds.\n    this.stopStream()\n  }, 10000)\n},\nmethods: {\n  async startStream() {\n    this.userStream = await leylo.streamPath(\n      \"users\",\n      user =\u003e {\n        this.greetingList.push(`Hello ${user.data().firstName}`);\n      },\n      \"added\",\n      false\n    );\n  },\n  async stopStream() {\n    // Firestore's detachment is odd. You have to call the stream as a function:\n    this.userStream();\n  }\n}\n\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.streamDocChangesById(collection, id[, callback, changeType, getData?])`\n\nReturns result of passing document `Object` as parameter to `callback` every time the document is modified\n\n- `collection` **[String]** - Name of collection\n- `id` **[String]** - Name/ID of document within collection\n- `callback` **[Function]** (_Default: null_) - Function to execute on every change to document\n- `changeType` **[String]** (_Default: null_) - If `null` listen to all, else one of `added`, `modified`, or `removed`\n- `getData` **[Boolean]** (_Default: true_) - If `true` passes `querySnapshot.docChanges().data()` to `callback` else passes `querySnapshot.docChanges()`\n\n```js\n\n// Can do this during created(), mounted() or some init function\nlet messages = await leylo.streamDocChangesById(\n  \"messages\",\n  \"chatroomA\",\n  newdata =\u003e {\n    // Executes every time a field is added, modified, or removed from this document\n    console.log(\"Document has changed to:\");\n    console.log(newdata);\n  }\n);\n\nlet userList = await leylo.streamDocChangesById(\n  \"users\",\n  \"chatroomA\",\n  this.addUser,\n  'added',\n  false\n);\n\n// Passing the data from above stream into one of our component's methods:\nmethods: {\n  addUser(doc) {\n    console.log(`New user was added at ${doc.ref.path} with contents:`)\n    console.log(doc.data())\n  }\n}\n\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.streamDocChangesByField(collection, field, value[, callback, changeType, getData?])`\n\nReturns result of passing document `Object` as parameter to `callback` every time a document's field is modified\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key/field of target document\n- `value` **[String]** - Value of key/field of target document\n- `callback` **[Function]** (_Default: null_) - Function to execute on every change to document\n- `changeType` **[String]** (_Default: null_) - If `null` listen to all, else one of `added`, `modified`, or `removed`\n- `getData` **[Boolean]** (_Default: true_) - If `true` passes `querySnapshot.docChanges().data()` to `callback` else passes `querySnapshot.docChanges()`\n\n```js\nlet usersCurrentlyInArizona = await leylo.streamDocChangesByField(\n  \"users\",\n  \"location\",\n  \"Arizona\"(doc =\u003e {\n    console.log(`${doc.ref.path} is now in Arizona`);\n  }),\n  \"modified\",\n  false\n);\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--retreiving-data)\u0026nbsp;\u0026nbsp; `.streamDocChangesByQuery(collection, field, query, value[, callback, changeType, getData?])`\n\nReturns **every matching** result of passing document `Object` as parameter to `callback` every time the document is modified\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key/field of target document\n- `query` **[String]** - One of `==`, `\u003e=`, `\u003c=`, `\u003e`, `\u003c`, `array_contains` or valid Firebase query string\n- `value` **[String]** - Value of key/field of target document\n- `callback` **[Function]** (_Default: null_) - Function to execute on every change to document\n- `changeType` **[String]** (_Default: null_) - If `null` listen to all, else one of `added`, `modified`, or `removed`\n- `getData` **[Boolean]** (_Default: true_) - If `true` passes `querySnapshot.docChanges().data()` to `callback` else passes `querySnapshot.docChanges()`\n\n```js\nlet usersLeavingArizona = await leylo.streamDocChangesByField(\n  \"users\",\n  \"temperature\",\n  \"\u003c=\",\n  110,\n  doc =\u003e {\n    console.log(`${doc.ref.path} has left Arizona`);\n  },\n  \"modified\",\n  false\n);\n```\n\n\u003cbr\u003e\n\n---\n\n## \u0026nbsp;\u0026nbsp;[◤](#-api)\u0026nbsp;\u0026nbsp; 📘 Adding Data\n\n- [leylo.addDoc()](#-adddoccollection-data)\n- [leylo.addAllDocs()](#-addalldocscollection-docs)\n- [leylo.setPath()](#-setpathpath-data-overwrite)\n- [leylo.setDocByPath()](#-setdocbypathpath-data-overwrite)\n- [leylo.setAllDocsByPath()](#-setalldocsbypathoverwrite-docs)\n- [leylo.setDocById()](#-setdocbyidcollection-id-data-overwrite)\n- [leylo.setAllDocsById()](#-setalldocsbyidcollection-overwrite-docs)\n- [leylo.setFieldByPath()](#-setfieldbypathpath-value)\n- [leylo.setFieldById()](#-setfieldbyidcollection-id-field-value)\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--adding-data)\u0026nbsp;\u0026nbsp; `.addDoc(collection, data)`\n\nReturns `DocumentReference` result of writing new document with auto-generated id to `collection`\n\n- `collection` **[String]** - Name of collection\n- `data` **[Object]** - Contents of document to write\n\n```js\nlet user = await leylo.addDoc(\"users\", {\n  name: \"Random\",\n  location: \"Random\"\n});\n\nconsole.log(user); //  Returns DocumentSnapshot{ ... }\nconsole.log(user.id); //  Returns 'cmeJ6JeoTCIfvMvgE2ru', auto-generated id\nconsole.log(user.ref.path); //  Returns 'users/cmeJ6JeoTCIfvMvgE2ru'\nconsole.log(user.data()); //  Returns { name: 'Random', location: 'Random' }\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--adding-data)\u0026nbsp;\u0026nbsp; `.addAllDocs(collection, ...docs)`\n\nReturns `Array` of `DocumentReference`s of newly written documents to `collection`\n\n- `collection` **[String]** - Name of collection\n- `docs` **[Array]** - Array containing `Object`s to be written as documents (without ids)\n\n```js\nlet newUsers = await leylo.addAllDocs(\n  \"users\",\n  ...[{ name: \"SomeGuy\" }, { name: \"SomeGirl\" }]\n);\nconsole.log(docsCreatedWithGeneratedIds); // Returns [DocumentReference, DocumentReference]\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--adding-data)\u0026nbsp;\u0026nbsp; `.setPath(path, data[, overwrite?])`\n\n\u003e Shorthand method for writing document or field, will parse `path` and redirect to either leylo.addDoc(), leylo.addDocById(), or leylo.setFieldByPath()\n\nReturns `Boolean` of whether the document/field was successfully written or `Object` DocumentReference if path was only a collection\n\n- `path` **[String]** - Path in the form collection/document\n- `data` **[Any]** - Contents of document to write or append. If writing document, should be `Object`, but if field can be anything (except for `Array` within `Array` per Firestore limitation)\n- `overwrite` **[Boolean]** (_Default: false_) - If `false`, merge new `data` with pre-existing document or overwrite if it already exists, but if `true` replace document entirely with new `data`\n\n```js\n// Can be used to create new document or merge/add field into pre-existing document\nlet setLocation = await leylo.setPath(\"users/Inventsable\", {\n  location: \"Colorado\"\n});\nconsole.log(setLocation); //  Returns true\n\n// If path is only collection, adds new document and returns new document reference. This cannot be used to modify any pre-existing document.\nlet newUser = await leylo.setPath(\"users\", {\n  name: \"John Doe\",\n  location: \"Washington\"\n});\nconsole.log(newUser); //  Returns DocumentReference{ ... }\n\n// Rewrite individual field:\nlet rewriteUserData = await leylo.setPath(\n  \"users/Inventsable/location\",\n  \"Arizona\"\n);\nconsole.log(rewriteUserData); //  Returns true\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--adding-data)\u0026nbsp;\u0026nbsp; `.setDocByPath(path, data[, overwrite?])`\n\n\u003e Unlike leylo.setPath(), this method will return an Error if path points to collection or field.\n\nReturns `Boolean` of whether the document was successfully written to collection\n\n- `path` **[String]** - Path in the form collection/document\n- `data` **[Object]** - Contents of document to write or append\n- `overwrite` **[Boolean]** (_Default: false_) - If `false`, merge new `data` with pre-existing document or overwrite if it already exists, but if `true` replace document entirely with new `data`\n\n```js\n// If user 'Inventsable' already has content but no location, merge it as a new field:\nlet setLocation = await leylo.setDocByPath(\"users/Inventsable\", {\n  location: \"Colorado\"\n});\nconsole.log(setLocation); //  Returns true\n\n// If location already existed, rewrite it's contents to the new value:\nlet rewriteLocation = await leylo.setDocByPath(\"users/Inventsable\", {\n  location: \"Washington\"\n});\nconsole.log(rewriteLocation); //  Returns true\n\n// If overwrite is true, replace document at path entirely:\nlet rewriteUserData = await leylo.setDocByPath(\n  \"users/Inventsable\",\n  {\n    name: \"Tom Scharstein\",\n    location: \"Tempe\",\n    status: \"Working\"\n  },\n  true\n);\n\nconsole.log(rewriteUserData); //  Returns true\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--adding-data)\u0026nbsp;\u0026nbsp; `.setAllDocsByPath(overwrite, ...docs)`\n\nReturns `Array` of `Boolean`s the length of `docs` array for whether document was successfully written to Firestore\n\n- `data` **[Object]** - Contents of document to write or append\n- `overwrite` **[Boolean]** (_Default: false_) - If `false`, merge new `data` with pre-existing document or overwrite if it already exists, but if `true` replace document entirely with new `data`\n\n```js\n// Each data is an array in the form [ 'path', contents]\nlet users = [\n  [\"users/Inventsable\", { name: \"Tom\" }],\n  [\"users/somePerson\", { name: \"John\" }],\n  [\"users/someOtherPerson\", { name: \"Jane\" }]\n];\n\nlet writeUsers = await leylo.setAllDocsByPath(true, ...users);\nconsole.log(writeUsers); // Returns [true, true, true]\n\nlet newLocations = [\n  [\"users/Inventsable\", { location: \"Arizona\" }],\n  [\"users/somePerson\", { location: \"Arizona\" }],\n  [\"users/someOtherPerson\", { location: \"Arizona\" }]\n];\n\nlet mergeNewLocations = await leylo.setAllDocsByPath(false, ...newLocations);\nconsole.log(writeUsers); // Returns [true, true, true]\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--adding-data)\u0026nbsp;\u0026nbsp; `.setDocById(collection, id, data[, overwrite?])`\n\nReturns `Boolean` of whether the document was successfully written to collection\n\n- `collection` **[String]** - Name of collection\n- `id` **[String]** - Name/ID of document within collection\n- `data` **[Object]** - Contents of document to write\n- `overwrite` **[Boolean]** (_Default: false_) - If `false`, merge new `data` with pre-existing document, but if `true` replace document entirely with new `data`\n\n```js\nlet setAnotherLocation = await leylo.setDocById(\n  \"users\",\n  \"Inventsable\",\n  { location: \"Colorado\" },\n  false\n);\nconsole.log(setAnotherLocation);\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--adding-data)\u0026nbsp;\u0026nbsp; `.setAllDocsById(collection, overwrite, ...docs)`\n\nReturns `Array` of `Boolean`s the length of `docs` array for whether document was successfully written to Firestore\n\n- `collection` **[String]** - Name of collection\n- `overwrite` **[Boolean]** (_Default: false_) - If `false`, merge new `data` with pre-existing document, but if `true` replace document entirely with new `data`\n- `docs` **[Array]** - Contents of document to write as `[ 'id', contents ]`\n\n```js\n// Each document is an array in the form [ 'id', contents]\nlet users = [\n  [\"Inventsable\", { name: \"Tom\" }],\n  [\"SomeNameHere\", { name: \"John\" }],\n  [\"ScreenName\", { name: \"Jane\" }]\n];\n\nlet writeUsers = await leylo.setAllDocsById(\"users\", true, ...users);\nconsole.log(writeUsers); // Returns [true, true, true]\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--adding-data)\u0026nbsp;\u0026nbsp; `.setFieldByPath(path, value)`\n\nReturns `Boolean` of whether the field was successfully written to `path`\n\n- `path` **[String]** - Path in the form collection/document/field\n- `value` **[Any]** - New value to write to specified `path`\n\n```js\nlet updateUserLocation = await leylo.setFieldByPath(\n  \"users/Inventsable/location\",\n  \"Alaska\"\n);\nconsole.log(updateUserLocation); //  Returns true\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--adding-data)\u0026nbsp;\u0026nbsp; `.setFieldById(collection, id, field, value)`\n\nReturns `Boolean` of whether the field was successfully written to `path`\n\n- `collection` **[String]** - Name of collection\n- `id` **[String]** - Name/ID of document within collection\n- `field` **[String]** - Name of key within document\n- `value` **[Any]** - New value to write to specified `path`\n\n```js\nlet setNewLocation = await leylo.setFieldByDocId(\n  \"users\",\n  \"Inventsable\",\n  \"location\",\n  \"Colorado\"\n);\nconsole.log(setNewLocation);\n```\n\n\u003cbr\u003e\n\n---\n\n## \u0026nbsp;\u0026nbsp;[◤](#-api)\u0026nbsp;\u0026nbsp; 📕 Deleting Data\n\n- [leylo.deletePath()](#-deletepathpath)\n- [leylo.deleteCollection()](#-deletecollectioncollection)\n- [leylo.deleteDocById()](#-deletedocbyidcollection-id)\n- [leylo.deleteAllDocsByField()](#-deletealldocsbyfieldcollection-field-value)\n- [leylo.deleteAllDocsByQuery()](#-deletealldocsbyquerycollection-field-query-value)\n- [leylo.deleteFieldByDocId()](#-deletefieldbydocidcollection-id-field)\n- [leylo.deleteAllFieldsContainingValue()](#-deleteallfieldscontainingvaluecollection-field-value)\n- [leylo.deleteAllFieldsByQuery()](#-deleteallfieldsbyquerycollection-field-query-value)\n\n---\n\n### \u0026nbsp;\u0026nbsp;[▲](#--deleting-data)\u0026nbsp;\u0026nbsp; `.deletePath(path)`\n\n\u003e NOTE: If deleting a collection which has a stream, the stream is automatically detached.\n\nReturns `Boolean` if path was successfully deleted\n\n- `path` **[String]** - Any valid path from `collection` to `collection/document/field`\n\n```js\nlet deleteCertainUser = await leylo.deletePath(\"users/Inventsable\");\n\nif (deleteCertainUser) console.log(\"I was deleted!\");\n\n// Delete entire collection:\nleylo.deletePath(\"users\").then(result =\u003e {\n  console.log(result); // Returns true\n});\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--deleting-data)\u0026nbsp;\u0026nbsp; `.deleteCollection(collection)`\n\n\u003e Same as using `await leylo.deletePath(collection)`\n\nReturns `Array` of `Booleans` for number of documents successfully deleted\n\n- `collection` **[String]** - Name of collection\n\n```js\n// Delete entire collection:\nleylo.deleteCollection(\"users\").then(result =\u003e {\n  console.log(result); // Returns true\n});\n\nlet fullDeletion = await leylo.deleteCollection(\"users\");\nconsole.log(fullDeletion); // Returns false because collection doesn't exist, was deleted above\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--deleting-data)\u0026nbsp;\u0026nbsp; `.deleteDocById(collection, id)`\n\nReturns `Boolean`\n\n- `collection` **[String]** - Name of collection\n- `id` **[String]** - Name/ID of document within collection\n\n```js\nlet deleteCertainUser = await leylo.deletePath(\"users\", \"Inventsable\");\nconsole.log(deleteCertainUser); // Returns true\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--deleting-data)\u0026nbsp;\u0026nbsp; `.deleteAllDocsByField(collection, field, value)`\n\nReturns `Array` of `Booleans` for whether documents were successfully deleted\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key within document\n- `value` **[Any]** - New value to write to specified `path`\n\n```js\nlet deleteAllArizonaResidents = await leylo.deleteAllDocsByField(\n  \"users\",\n  \"location\",\n  \"Arizona\"\n);\nconsole.log(deleteAllArizonaResidents); // Returns [ true, true, true ]\n\ndeleteAllArizonaResidents.forEach(status =\u003e {\n  console.log(status); // Returns true\n});\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--deleting-data)\u0026nbsp;\u0026nbsp; `.deleteAllDocsByQuery(collection, field, query, value)`\n\nReturns `Array` of `Booleans` for whether docs were successfully deleted\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key within document\n- `query` **[String]** - One of `==`, `\u003e=`, `\u003c=`, `\u003e`, `\u003c`, `array_contains` or valid Firebase query string\n- `value` **[Any]** - New value to write to specified `path`\n\n```js\nlet deleteAllArizonaResidents = await leylo.deleteAllDocsByQuery(\n  \"users\",\n  \"temperature\",\n  \"\u003e=\",\n  110\n);\nconsole.log(deleteAllArizonaResidents); // Returns [ true, true, true ]\n\ndeleteAllArizonaResidents.forEach(status =\u003e {\n  console.log(status); // Returns true\n});\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--deleting-data)\u0026nbsp;\u0026nbsp; `.deleteFieldByDocId(collection, id, field)`\n\nReturns `Boolean` for whether field was successfully deleted from document\n\n- `collection` **[String]** - Name of collection\n- `id` **[String]** - Name/ID of document within collection\n- `field` **[String]** - Name of key within document\n\n```js\nlet deleteLocation = await leylo.deleteFieldByDocId(\n  \"users\",\n  \"Inventsable\",\n  \"location\"\n);\n\nconsole.log(deleteLocation); //  Returns true\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--deleting-data)\u0026nbsp;\u0026nbsp; `.deleteAllFieldsContainingValue(collection, field, value)`\n\nReturns `Array` of `Booleans` for whether fields were successfully deleted\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key within document\n- `value` **[Any]** - New value to write to specified `path`\n\n```js\nlet deleteAllArizonaLocations = await leylo.deleteAllFieldsContainingValue(\n  \"users\",\n  \"location\",\n  \"Arizona\"\n);\nconsole.log(deleteAllArizonaResidents); // Returns [ true, true, true ]\n\ndeleteAllArizonaResidents.forEach(status =\u003e {\n  console.log(status); // Returns true\n});\n\n// Unlike leylo.deleteAllDocsByQuery() or like, this only deletes the field 'location' instead of entire doc.\n```\n\n\u003cbr\u003e\n\n### \u0026nbsp;\u0026nbsp;[▲](#--deleting-data)\u0026nbsp;\u0026nbsp; `.deleteAllFieldsByQuery(collection, field, query, value)`\n\nReturns `Array` of `Booleans` for whether fields were successfully deleted\n\n- `collection` **[String]** - Name of collection\n- `field` **[String]** - Name of key within document\n- `query` **[String]** - One of `==`, `\u003e=`, `\u003c=`, `\u003e`, `\u003c`, `array_contains` or valid Firebase query string\n- `value` **[Any]** - New value to write to specified `path`\n\n```js\nlet deleteAllArizonaLocations = await leylo.deleteAllFieldsContainingValue(\n  \"users\",\n  \"location\",\n  \"==\",\n  \"Arizona\"\n);\nconsole.log(deleteAllArizonaLocations); // Returns [ true, true, true ]\n\ndeleteAllArizonaLocations.forEach(status =\u003e {\n  console.log(status); //  Returns true\n});\n\nlet deleteAllAlaskaLocations = await leylo.deleteAllFieldsContainingValue(\n  \"users\",\n  \"temperature\",\n  \"\u003c=\",\n  10\n);\nconsole.log(deleteAllAlaskaLocations); // Returns [ true, true, true ]\ndeleteAllAlaskaLocations.forEach(status =\u003e {\n  console.log(status); //  Returns true\n});\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finventsable%2Fleylo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finventsable%2Fleylo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finventsable%2Fleylo/lists"}