Skip to content

Instantly share code, notes, and snippets.

@christianlacerda
Last active April 28, 2023 05:18
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save christianlacerda/8de3de6af5862c63f02db6f3eaa9334a to your computer and use it in GitHub Desktop.
Save christianlacerda/8de3de6af5862c63f02db6f3eaa9334a 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,
};
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;
@tomorroN
Copy link

tomorroN commented Feb 3, 2020

May be useful:

WRITTEN: (fieldBefore: any, fieldAfter: any) =>
(fieldBefore === undefined && fieldAfter) ||
(fieldBefore && fieldAfter === undefined) ||
!isEquivalent(fieldBefore, fieldAfter)

It's like CHANGED condition, but includes ADD and REMOVE conditions

@tomriddle25
Copy link

I am guessing this only works for the admin sdk?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment