fix(android, firestore): detach snapshot listeners before executor shutdown#8940
Conversation
…utdown Remove Firestore listeners before super.invalidate() so TaskExecutorService is not shut down while snapshot callbacks may still run sendOnSnapshotEvent (Tasks.call on a transactional executor). Aligns with ReactNativeFirebaseFirestoreTransactionModule teardown order. Fixes invertase#8939 Made-with: Cursor
|
@christian-apollo is attempting to deploy a commit to the Invertase Team on Vercel. A member of the Team first needs to authorize it. |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a potential crash in Android when React Native modules are invalidated. By adjusting the order of operations during module teardown, it ensures that Firestore snapshot listeners are properly unregistered before the underlying executor service is shut down, thereby preventing runtime exceptions and improving application stability. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request refactors the invalidate method in ReactNativeFirebaseFirestoreCollectionModule and ReactNativeFirebaseFirestoreDocumentModule. The super.invalidate() call is moved to the end of the method to ensure that module-specific listener cleanup and collection clearing occur before the superclass's invalidation logic. The review comments suggest an improvement to iterate SparseArrays using valueAt(i) for better readability and slightly improved performance.
| int key = collectionSnapshotListeners.keyAt(i); | ||
| ListenerRegistration listenerRegistration = collectionSnapshotListeners.get(key); |
There was a problem hiding this comment.
For improved readability and slightly better performance when iterating a SparseArray, you can use valueAt(i) to directly get the value at the current index instead of getting the key and then performing a lookup.
| int key = collectionSnapshotListeners.keyAt(i); | |
| ListenerRegistration listenerRegistration = collectionSnapshotListeners.get(key); | |
| ListenerRegistration listenerRegistration = collectionSnapshotListeners.valueAt(i); |
| int key = documentSnapshotListeners.keyAt(i); | ||
| ListenerRegistration listenerRegistration = documentSnapshotListeners.get(key); |
There was a problem hiding this comment.
For improved readability and slightly better performance when iterating a SparseArray, you can use valueAt(i) to directly get the value at the current index instead of getting the key and then performing a lookup.
| int key = documentSnapshotListeners.keyAt(i); | |
| ListenerRegistration listenerRegistration = documentSnapshotListeners.get(key); | |
| ListenerRegistration listenerRegistration = documentSnapshotListeners.valueAt(i); |
|
Hey @christian-apollo 👋 - thanks for this - could you follow the link in either the comment or the CI check to read+accept the CLA? Happy to collaborate and merge but we have to have the CLA signed to take in code, thanks! |
mikehardy
left a comment
There was a problem hiding this comment.
Looks like a nice fix
I'm okay with ignoring the suggested readability/performance optimizations from LLM review as I do not believe this will execute very frequently at all nor do I think the set of listeners will ever be large, it just doesn't seem consequential
waiting on CLA approval
|
signed! |
Summary
Removes Firestore snapshot listeners before
super.invalidate()inReactNativeFirebaseFirestoreCollectionModuleandReactNativeFirebaseFirestoreDocumentModule.ReactNativeFirebaseModule.invalidate()shuts downTaskExecutorService;sendOnSnapshotEventusesTasks.call(getTransactionalExecutor(...), ...). If the executor is terminated first, a late snapshot can throwRejectedExecutionException(terminated pool).This matches the teardown order already used in
ReactNativeFirebaseFirestoreTransactionModule.Related issue
Test plan
onSnapshot, trigger RN reload or scenario that invalidates native modules; confirm no crash (manual / existing e2e if any)Made with Cursor