Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ public class ReactNativeFirebaseDatabaseQueryModule extends ReactNativeFirebaseM

@Override
public void invalidate() {
super.invalidate();

Iterator refIterator = queryMap.entrySet().iterator();
while (refIterator.hasNext()) {
Map.Entry pair = (Map.Entry) refIterator.next();
Expand All @@ -53,6 +51,8 @@ public void invalidate() {
databaseQuery.removeAllEventListeners();
refIterator.remove(); // avoids a ConcurrentModificationException
}

super.invalidate();
}

/**
Expand Down Expand Up @@ -101,15 +101,19 @@ private void addOnceValueEventListener(
new ValueEventListener() {
@Override
public void onDataChange(@Nonnull DataSnapshot dataSnapshot) {
Tasks.call(getExecutor(), () -> snapshotToMap(dataSnapshot))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseWithExceptionMap(promise, task.getException());
}
});
try {
Tasks.call(getExecutor(), () -> snapshotToMap(dataSnapshot))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseWithExceptionMap(promise, task.getException());
}
});
} catch (java.util.concurrent.RejectedExecutionException e) {
rejectPromiseWithExceptionMap(promise, e);
}
}

@Override
Expand Down Expand Up @@ -139,69 +143,85 @@ private void addChildOnceEventListener(
public void onChildAdded(@Nonnull DataSnapshot dataSnapshot, String previousChildName) {
if ("child_added".equals(eventType)) {
databaseQuery.removeEventListener(this);
Tasks.call(
getExecutor(),
() -> snapshotWithPreviousChildToMap(dataSnapshot, previousChildName))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseWithExceptionMap(promise, task.getException());
}
});
try {
Tasks.call(
getExecutor(),
() -> snapshotWithPreviousChildToMap(dataSnapshot, previousChildName))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseWithExceptionMap(promise, task.getException());
}
});
} catch (java.util.concurrent.RejectedExecutionException e) {
rejectPromiseWithExceptionMap(promise, e);
}
}
}

@Override
public void onChildChanged(@Nonnull DataSnapshot dataSnapshot, String previousChildName) {
if ("child_changed".equals(eventType)) {
databaseQuery.removeEventListener(this);
Tasks.call(
getExecutor(),
() -> snapshotWithPreviousChildToMap(dataSnapshot, previousChildName))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseWithExceptionMap(promise, task.getException());
}
});
try {
Tasks.call(
getExecutor(),
() -> snapshotWithPreviousChildToMap(dataSnapshot, previousChildName))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseWithExceptionMap(promise, task.getException());
}
});
} catch (java.util.concurrent.RejectedExecutionException e) {
rejectPromiseWithExceptionMap(promise, e);
}
}
}

@Override
public void onChildRemoved(@Nonnull DataSnapshot dataSnapshot) {
if ("child_removed".equals(eventType)) {
databaseQuery.removeEventListener(this);
Tasks.call(getExecutor(), () -> snapshotWithPreviousChildToMap(dataSnapshot, null))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseWithExceptionMap(promise, task.getException());
}
});
try {
Tasks.call(getExecutor(), () -> snapshotWithPreviousChildToMap(dataSnapshot, null))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseWithExceptionMap(promise, task.getException());
}
});
} catch (java.util.concurrent.RejectedExecutionException e) {
rejectPromiseWithExceptionMap(promise, e);
}
}
}

@Override
public void onChildMoved(@Nonnull DataSnapshot dataSnapshot, String previousChildName) {
if ("child_moved".equals(eventType)) {
databaseQuery.removeEventListener(this);
Tasks.call(
getExecutor(),
() -> snapshotWithPreviousChildToMap(dataSnapshot, previousChildName))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseWithExceptionMap(promise, task.getException());
}
});
try {
Tasks.call(
getExecutor(),
() -> snapshotWithPreviousChildToMap(dataSnapshot, previousChildName))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseWithExceptionMap(promise, task.getException());
}
});
} catch (java.util.concurrent.RejectedExecutionException e) {
rejectPromiseWithExceptionMap(promise, e);
}
}
}

Expand Down Expand Up @@ -315,34 +335,39 @@ private void handleDatabaseEvent(
DataSnapshot dataSnapshot,
@Nullable String previousChildName) {
final String eventRegistrationKey = registration.getString("eventRegistrationKey");
Tasks.call(
getTransactionalExecutor(eventRegistrationKey),
() -> {
if (eventType.equals("value")) {
return snapshotToMap(dataSnapshot);
} else {
return snapshotWithPreviousChildToMap(dataSnapshot, previousChildName);
}
})
.addOnCompleteListener(
getExecutor(),
task -> {
if (task.isSuccessful()) {
WritableMap data = task.getResult();
WritableMap event = Arguments.createMap();
event.putMap("data", data);
event.putString("key", key);
event.putString("eventType", eventType);
event.putMap("registration", readableMapToWritableMap(registration));

ReactNativeFirebaseEventEmitter emitter =
ReactNativeFirebaseEventEmitter.getSharedInstance();

emitter.sendEvent(
new ReactNativeFirebaseDatabaseEvent(
ReactNativeFirebaseDatabaseEvent.EVENT_SYNC, event));
}
});
try {
Tasks.call(
getTransactionalExecutor(eventRegistrationKey),
() -> {
if (eventType.equals("value")) {
return snapshotToMap(dataSnapshot);
} else {
return snapshotWithPreviousChildToMap(dataSnapshot, previousChildName);
}
})
.addOnCompleteListener(
getExecutor(),
task -> {
if (task.isSuccessful()) {
WritableMap data = task.getResult();
WritableMap event = Arguments.createMap();
event.putMap("data", data);
event.putString("key", key);
event.putString("eventType", eventType);
event.putMap("registration", readableMapToWritableMap(registration));

ReactNativeFirebaseEventEmitter emitter =
ReactNativeFirebaseEventEmitter.getSharedInstance();

emitter.sendEvent(
new ReactNativeFirebaseDatabaseEvent(
ReactNativeFirebaseDatabaseEvent.EVENT_SYNC, event));
}
});
} catch (java.util.concurrent.RejectedExecutionException e) {
// Event arrived after module invalidation shut down an executor.
// Safe to drop when tearing down; no JS listener will consume the event.
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,16 +389,20 @@ private void handleQueryOnSnapshot(

private void handleQueryGet(
ReactNativeFirebaseFirestoreQuery firestoreQuery, Source source, Promise promise) {
firestoreQuery
.get(getExecutor(), source)
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseFirestoreException(promise, task.getException());
}
});
try {
firestoreQuery
.get(getExecutor(), source)
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult());
} else {
rejectPromiseFirestoreException(promise, task.getException());
}
});
} catch (java.util.concurrent.RejectedExecutionException e) {
rejectPromiseFirestoreException(promise, e);
}
}

private void sendOnSnapshotEvent(
Expand All @@ -407,31 +411,36 @@ private void sendOnSnapshotEvent(
int listenerId,
QuerySnapshot querySnapshot,
MetadataChanges metadataChanges) {
Tasks.call(
getTransactionalExecutor(Integer.toString(listenerId)),
() ->
snapshotToWritableMap(
appName, databaseId, "onSnapshot", querySnapshot, metadataChanges))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
WritableMap body = Arguments.createMap();
body.putMap("snapshot", task.getResult());

ReactNativeFirebaseEventEmitter emitter =
ReactNativeFirebaseEventEmitter.getSharedInstance();

emitter.sendEvent(
new ReactNativeFirebaseFirestoreEvent(
ReactNativeFirebaseFirestoreEvent.COLLECTION_EVENT_SYNC,
body,
appName,
databaseId,
listenerId));
} else {
sendOnSnapshotError(appName, databaseId, listenerId, task.getException());
}
});
try {
Tasks.call(
getTransactionalExecutor(Integer.toString(listenerId)),
() ->
snapshotToWritableMap(
appName, databaseId, "onSnapshot", querySnapshot, metadataChanges))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
WritableMap body = Arguments.createMap();
body.putMap("snapshot", task.getResult());

ReactNativeFirebaseEventEmitter emitter =
ReactNativeFirebaseEventEmitter.getSharedInstance();

emitter.sendEvent(
new ReactNativeFirebaseFirestoreEvent(
ReactNativeFirebaseFirestoreEvent.COLLECTION_EVENT_SYNC,
body,
appName,
databaseId,
listenerId));
} else {
sendOnSnapshotError(appName, databaseId, listenerId, task.getException());
}
});
} catch (java.util.concurrent.RejectedExecutionException e) {
// Snapshot arrived after module invalidation shut down the executor.
// Safe to drop — the module is being torn down and no JS listener remains.
}
}

private void sendOnSnapshotError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,27 +300,32 @@ public void documentBatch(

private void sendOnSnapshotEvent(
String appName, String databaseId, int listenerId, DocumentSnapshot documentSnapshot) {
Tasks.call(getExecutor(), () -> snapshotToWritableMap(appName, databaseId, documentSnapshot))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
WritableMap body = Arguments.createMap();
body.putMap("snapshot", task.getResult());

ReactNativeFirebaseEventEmitter emitter =
ReactNativeFirebaseEventEmitter.getSharedInstance();

emitter.sendEvent(
new ReactNativeFirebaseFirestoreEvent(
ReactNativeFirebaseFirestoreEvent.DOCUMENT_EVENT_SYNC,
body,
appName,
databaseId,
listenerId));
} else {
sendOnSnapshotError(appName, databaseId, listenerId, task.getException());
}
});
try {
Tasks.call(getExecutor(), () -> snapshotToWritableMap(appName, databaseId, documentSnapshot))
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
WritableMap body = Arguments.createMap();
body.putMap("snapshot", task.getResult());

ReactNativeFirebaseEventEmitter emitter =
ReactNativeFirebaseEventEmitter.getSharedInstance();

emitter.sendEvent(
new ReactNativeFirebaseFirestoreEvent(
ReactNativeFirebaseFirestoreEvent.DOCUMENT_EVENT_SYNC,
body,
appName,
databaseId,
listenerId));
} else {
sendOnSnapshotError(appName, databaseId, listenerId, task.getException());
}
});
} catch (java.util.concurrent.RejectedExecutionException e) {
// Snapshot arrived after module invalidation shut down the executor.
// Safe to drop — the module is being torn down and no JS listener remains.
}
}

private void sendOnSnapshotError(
Expand Down
Loading
Loading