Skip to content

Commit 8d63eac

Browse files
Fix cancelCallback for child_added events (#4832)
1 parent ba2b11f commit 8d63eac

File tree

2 files changed

+23
-53
lines changed

2 files changed

+23
-53
lines changed

.changeset/fluffy-oranges-cross.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@firebase/database": patch
3+
---
4+
5+
Fixes an issue that prevented the SDK from firing cancel events for Rules violations.

packages/database/src/exp/Reference_impl.ts

+18-53
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { assert, contains, getModularInstance, Deferred } from '@firebase/util';
18+
import { assert, getModularInstance, Deferred } from '@firebase/util';
1919

2020
import {
2121
Repo,
@@ -870,28 +870,24 @@ export class ValueEventRegistration implements EventRegistration {
870870
}
871871

872872
/**
873-
* Represents the registration of 1 or more child_xxx events.
874-
*
875-
* Currently, it is always exactly 1 child_xxx event, but the idea is we might
876-
* let you register a group of callbacks together in the future.
873+
* Represents the registration of a child_x event.
877874
*/
878875
export class ChildEventRegistration implements EventRegistration {
879876
constructor(
880-
private callbacks: {
881-
[child: string]: CallbackContext;
882-
} | null
877+
private eventType: string,
878+
private callbackContext: CallbackContext | null
883879
) {}
884880

885881
respondsTo(eventType: string): boolean {
886882
let eventToCheck =
887883
eventType === 'children_added' ? 'child_added' : eventType;
888884
eventToCheck =
889885
eventToCheck === 'children_removed' ? 'child_removed' : eventToCheck;
890-
return contains(this.callbacks, eventToCheck);
886+
return this.eventType === eventToCheck;
891887
}
892888

893889
createCancelEvent(error: Error, path: Path): CancelEvent | null {
894-
if (this.callbacks['cancel'].hasCancelCallback) {
890+
if (this.callbackContext.hasCancelCallback) {
895891
return new CancelEvent(this, error, path);
896892
} else {
897893
return null;
@@ -915,12 +911,11 @@ export class ChildEventRegistration implements EventRegistration {
915911

916912
getEventRunner(eventData: CancelEvent | DataEvent): () => void {
917913
if (eventData.getEventType() === 'cancel') {
918-
const cancelCB = this.callbacks['cancel'];
919-
return () => cancelCB.onCancel((eventData as CancelEvent).error);
914+
return () =>
915+
this.callbackContext.onCancel((eventData as CancelEvent).error);
920916
} else {
921-
const cb = this.callbacks[(eventData as DataEvent).eventType];
922917
return () =>
923-
cb.onValue(
918+
this.callbackContext.onValue(
924919
(eventData as DataEvent).snapshot,
925920
(eventData as DataEvent).prevName
926921
);
@@ -929,42 +924,19 @@ export class ChildEventRegistration implements EventRegistration {
929924

930925
matches(other: EventRegistration): boolean {
931926
if (other instanceof ChildEventRegistration) {
932-
if (!this.callbacks || !other.callbacks) {
933-
return true;
934-
} else {
935-
const otherKeys = Object.keys(other.callbacks);
936-
const thisKeys = Object.keys(this.callbacks);
937-
const otherCount = otherKeys.length;
938-
const thisCount = thisKeys.length;
939-
if (otherCount === thisCount) {
940-
// If count is 1, do an exact match on eventType, if either is defined but null, it's a match.
941-
// If event types don't match, not a match
942-
// If count is not 1, exact match across all
943-
944-
if (otherCount === 1) {
945-
const otherKey = otherKeys[0];
946-
const thisKey = thisKeys[0];
947-
return (
948-
thisKey === otherKey &&
949-
(!other.callbacks[otherKey] ||
950-
!this.callbacks[thisKey] ||
951-
other.callbacks[otherKey].matches(this.callbacks[thisKey]))
952-
);
953-
} else {
954-
// Exact match on each key.
955-
return thisKeys.every(eventType =>
956-
other.callbacks[eventType].matches(this.callbacks[eventType])
957-
);
958-
}
959-
}
960-
}
927+
return (
928+
this.eventType === other.eventType &&
929+
(!this.callbackContext ||
930+
!other.callbackContext ||
931+
this.callbackContext.matches(other.callbackContext))
932+
);
961933
}
962934

963935
return false;
964936
}
965937

966938
hasAnyCallback(): boolean {
967-
return this.callbacks !== null;
939+
return !!this.callbackContext;
968940
}
969941
}
970942

@@ -1002,9 +974,7 @@ function addEventListener(
1002974
const container =
1003975
eventType === 'value'
1004976
? new ValueEventRegistration(callbackContext)
1005-
: new ChildEventRegistration({
1006-
[eventType]: callbackContext
1007-
});
977+
: new ChildEventRegistration(eventType, callbackContext);
1008978
repoAddEventCallbackForQuery(query._repo, query, container);
1009979
return () => repoRemoveEventCallbackForQuery(query._repo, query, container);
1010980
}
@@ -1656,16 +1626,11 @@ export function off(
16561626
) => unknown
16571627
): void {
16581628
let container: EventRegistration | null = null;
1659-
let callbacks: { [k: string]: CallbackContext } | null = null;
16601629
const expCallback = callback ? new CallbackContext(callback) : null;
16611630
if (eventType === 'value') {
16621631
container = new ValueEventRegistration(expCallback);
16631632
} else if (eventType) {
1664-
if (callback) {
1665-
callbacks = {};
1666-
callbacks[eventType] = expCallback;
1667-
}
1668-
container = new ChildEventRegistration(callbacks);
1633+
container = new ChildEventRegistration(eventType, expCallback);
16691634
}
16701635
repoRemoveEventCallbackForQuery(query._repo, query, container);
16711636
}

0 commit comments

Comments
 (0)