firestore-auto-sync

<a href="https://www.npmjs.com/package/firestore-auto-sync"><img src="https://img.shields.io/npm/v/firestore-auto-sync.svg" alt="Total Downloads"></a> <a href="https://www.npmjs.com/package/firestore-auto-sync"><img src="https://img.shields.io/npm/dw/fire

Usage no npm install needed!

<script type="module">
  import firestoreAutoSync from 'https://cdn.skypack.dev/firestore-auto-sync';
</script>

README

🛞 firestore-auto-sync

Total Downloads Latest Stable Version

A function to import into your cloud functions to easily set up reactive updates & increments throughout your Firestore database.

npm i firestore-auto-sync

Reaction Example

import * as functions from "firebase-functions"
import { firebaseAutoSync } from "firestore-auto-sync"
import type { Reaction } from "firestore-auto-sync"
import type { Company } from "~/my-types"

const reaction: Reaction<Company> = {
  prop: "name", // when a company's record `name` field changes...
  updates: [    // make these updates:
    {
      collection: "invoices",      // for the `invoices` collection:
      keyOrigin: "id",             // 1. take the company record's `id` field
      keyTarget: "companyId",      // 2. find all `invoices` that have this same `id` at their `companyId` field
      propToUpdate: "companyName", // 3. copy the new company name to the invoice `companyName`
    },
    {
      collection: "users",
      keyOrigin: "id",
      keyTarget: "companyId",
      propToUpdate: "companyName",
    },
  ],
}

export const watchCompanies = functions
  .region(FIREBASE_REGION)
  .firestore.document("companies/{companyId}")
  .onWrite(async (change, context) => {
    await firebaseAutoSync({ change, reaction })
  })

Increment Example

Here is an example where on every school added a district and a global counts record is incremented.

import * as functions from "firebase-functions"
import { firebaseAutoSync } from "firestore-auto-sync"
import type { Increment } from "firestore-auto-sync"
import type { School } from "~/my-types"

const increment: Increment<School> = {
  // determine if we need to increment something
  incrementBy: (newData, oldData) => {
    if (newData && !oldData) {
      return 1  // on new document added increment by 1
    }
    if (!newData && oldData) {
      return -1 // on document deletion decrement by 1
    }
    return 0    // otherwise do nothing
  },
  increments: [
    {
      collection: "districts",           // for the `districts` collection:
      keyOrigin: "districtId",           // 1. take the school record's `districtId` field
      keyTarget: "id",                   // 2. find all `districts` that have this same `districtId` at their `id` field
      propToIncrement: "counts.schools", // 3. increment the value at `counts.school` (a nested object)
    },
    {
      doc: "adminDocs/stats",            // for the `adminDocs/stats` document:
      propToIncrement: "counts.schools", // 1. increment the value at `counts.school` (a nested object)
    },
  ],
}

export const watchSchool = functions.firestore
  .document("schools/{docId}")
  .onWrite(async (change, context) => {
    await firebaseAutoSync({ change, increment })
  })