From 7a8966522f06efb3f0303b2a3c6fd08f41d8aff9 Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Mon, 15 Apr 2024 10:29:46 -0500 Subject: [PATCH] fix: Live Query not working on Expo React Native (#2109) --- integration/test/ParseLiveQueryTest.js | 38 ++++++++++++++++++++++++++ src/LiveQueryClient.js | 4 +-- src/LiveQuerySubscription.js | 4 +-- src/ParseLiveQuery.js | 5 ++-- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/integration/test/ParseLiveQueryTest.js b/integration/test/ParseLiveQueryTest.js index c33f21a00..06a2c89d9 100644 --- a/integration/test/ParseLiveQueryTest.js +++ b/integration/test/ParseLiveQueryTest.js @@ -4,6 +4,7 @@ const assert = require('assert'); const Parse = require('../../node'); const sleep = require('./sleep'); const { resolvingPromise } = require('../../lib/node/promiseUtils'); +const { EventEmitter } = require('events'); describe('Parse LiveQuery', () => { beforeEach(() => { @@ -367,4 +368,41 @@ describe('Parse LiveQuery', () => { client.state = 'closed'; await client.close(); }); + + it('can subscribe to query with EventEmitter private fields', async () => { + class CustomEmitter { + #privateEmitter; + + constructor() { + this.#privateEmitter = new EventEmitter(); + } + on(event, listener) { + this.#privateEmitter.on(event, listener); + } + emit(event, ...args) { + this.#privateEmitter.emit(event, ...args); + } + } + + const EV = Parse.CoreManager.getEventEmitter(); + + Parse.CoreManager.setEventEmitter(CustomEmitter); + const object = new TestObject(); + await object.save(); + const installationId = await Parse.CoreManager.getInstallationController().currentInstallationId(); + + const query = new Parse.Query(TestObject); + query.equalTo('objectId', object.id); + const subscription = await query.subscribe(); + const promise = resolvingPromise(); + subscription.on('update', (object, original, response) => { + assert.equal(object.get('foo'), 'bar'); + assert.equal(response.installationId, installationId); + promise.resolve(); + }); + object.set({ foo: 'bar' }); + await object.save(); + await promise; + Parse.CoreManager.setEventEmitter(EV); + }); }); diff --git a/src/LiveQueryClient.js b/src/LiveQueryClient.js index b66a353fa..9c65ef74d 100644 --- a/src/LiveQueryClient.js +++ b/src/LiveQueryClient.js @@ -157,8 +157,8 @@ class LiveQueryClient { const EventEmitter = CoreManager.getEventEmitter(); this.emitter = new EventEmitter(); - this.on = this.emitter.on; - this.emit = this.emitter.emit; + this.on = (eventName, listener) => this.emitter.on(eventName, listener); + this.emit = (eventName, ...args) => this.emitter.emit(eventName, ...args); // adding listener so process does not crash // best practice is for developer to register their own listener this.on('error', () => {}); diff --git a/src/LiveQuerySubscription.js b/src/LiveQuerySubscription.js index c70d234c1..8a1368eb8 100644 --- a/src/LiveQuerySubscription.js +++ b/src/LiveQuerySubscription.js @@ -99,8 +99,8 @@ class Subscription { const EventEmitter = CoreManager.getEventEmitter(); this.emitter = new EventEmitter(); - this.on = this.emitter.on; - this.emit = this.emitter.emit; + this.on = (eventName, listener) => this.emitter.on(eventName, listener); + this.emit = (eventName, ...args) => this.emitter.emit(eventName, ...args); // adding listener so process does not crash // best practice is for developer to register their own listener this.on('error', () => {}); diff --git a/src/ParseLiveQuery.js b/src/ParseLiveQuery.js index eea9e59e2..c293133c7 100644 --- a/src/ParseLiveQuery.js +++ b/src/ParseLiveQuery.js @@ -39,9 +39,8 @@ class LiveQuery { constructor() { const EventEmitter = CoreManager.getEventEmitter(); this.emitter = new EventEmitter(); - this.on = this.emitter.on; - this.emit = this.emitter.emit; - + this.on = (eventName, listener) => this.emitter.on(eventName, listener); + this.emit = (eventName, ...args) => this.emitter.emit(eventName, ...args); // adding listener so process does not crash // best practice is for developer to register their own listener this.on('error', () => {});