Skip to content

Instantly share code, notes, and snippets.

@tomorroN
Forked from christianlacerda/firestore-field-filter.ts
Last active February 3, 2020 15:28
Show Gist options
  • Save tomorroN/5a1f9bee63f0101f1086b9cc5455b74c to your computer and use it in GitHub Desktop.
Save tomorroN/5a1f9bee63f0101f1086b9cc5455b74c to your computer and use it in GitHub Desktop.
Filters Firestore events based on field name and event type
import * as admin from 'firebase-admin';
import { Change, EventContext } from 'firebase-functions';
import { isEqual } from 'lodash';
import DocumentSnapshot = admin.firestore.DocumentSnapshot;
import FieldPath = admin.firestore.FieldPath;
const isEquivalent = (before: any, after: any) => {
return before && typeof before.isEqual === 'function'
? before.isEqual(after)
: isEqual(before, after);
};
const conditions = {
CHANGED: (fieldBefore: any, fieldAfter: any) =>
fieldBefore !== undefined &&
fieldAfter !== undefined &&
!isEquivalent(fieldBefore, fieldAfter),
ADDED: (fieldBefore: any, fieldAfter: any) =>
fieldBefore === undefined && fieldAfter,
REMOVED: (fieldBefore: any, fieldAfter: any) =>
fieldBefore && fieldAfter === undefined,
WRITTEN: (fieldBefore: any, fieldAfter: any) =>
(fieldBefore === undefined && fieldAfter) ||
(fieldBefore && fieldAfter === undefined) ||
!isEquivalent(fieldBefore, fieldAfter),
};
const field = (
fieldPath: string | FieldPath,
operation: 'ADDED' | 'REMOVED' | 'CHANGED',
handler: (
change: Change<DocumentSnapshot>,
context: EventContext,
) => PromiseLike<any> | any,
) => {
return function(change: Change<DocumentSnapshot>, context: EventContext) {
const fieldBefore = change.before.get(fieldPath);
const fieldAfter = change.after.get(fieldPath);
return conditions[operation](fieldBefore, fieldAfter)
? handler(change, context)
: Promise.resolve();
};
};
export default field;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment