react-native-firebase
react-native-firebase copied to clipboard
[🐛] removing secondary app listeners stops all projects listeners
Issue
- Create a secondary app ( or more)
- listen to a a similar path in the two apps
- remove listeners for the second app
- listeners stop working for the first app
import firebase from "@react-native-firebase/app"
import "@react-native-firebase/database"
const firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL:"",
projectId: "first-app",
storageBucket: "",
messagingSenderId: "",
appId: "",
};
const firebaseConfig2 = {
apiKey: "",
authDomain: "",
databaseURL:"",
projectId: "second-app",
storageBucket: "",
messagingSenderId: "",
appId: "",
};
// Initialize Firebase
const nodeRef = "users/be19e756-a51a-4f01-80fe-9a121c370957/cars";
firebase.initializeApp(firebaseConfig, { name: "first-app" });
firebase.initializeApp(firebaseConfig2, { name: "second-app" });
const app1Ins = firebase.app(firebaseConfig.projectId);
const app2Ins = firebase.app(firebaseConfig2.projectId);
app1Ins
.database()
.ref(nodeRef)
.on("child_added", (snapshot) => {
console.log("child_added", snapshot.val());
});
app1Ins
.database()
.ref(nodeRef)
.on("child_removed", (snapshot) => {
console.log("child_removed", snapshot.val());
});
app2Ins
.database()
.ref(nodeRef)
.on("child_added", (snapshot) => {
console.log("child_added", snapshot.val());
});
app2Ins
.database()
.ref(nodeRef)
.on("child_removed", (snapshot) => {
console.log("child_removed", snapshot.val());
});
setTimeout(() => {
console.log("remove listeners");
app2Ins.database().ref(nodeRef).off("child_added");
app2Ins.database().ref(nodeRef).off("child_removed");
}, 5000);
Project Files
Javascript
Click To Expand
package.json
:
{
"main": "index.js",
"scripts": {
"android": "expo run:android",
"ios": "expo run:ios",
"web": "expo start --web",
"start": "react-native start"
},
"dependencies": {
"expo": "~43.0.2",
"expo-splash-screen": "~0.13.5",
"@react-native-firebase/app": "13.1.0",
"@react-native-firebase/database": "13.1.0",
"expo-status-bar": "~1.1.0",
"expo-updates": "~0.10.13",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-gesture-handler": "~1.10.2",
"react-native-reanimated": "~2.2.0",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "~3.8.0",
"react-native-web": "0.17.1"
},
"devDependencies": {
"@babel/core": "^7.12.9"
},
"private": true
}
firebase.json
for react-native-firebase v6:
# N/A
iOS
Click To Expand
ios/Podfile
:
- [ ] I'm not using Pods
- [x] I'm using Pods and my Podfile looks like:
# N/A
AppDelegate.m
:
// N/A
Android
Click To Expand
Have you converted to AndroidX?
- [ ] my application is an AndroidX application?
- [ ] I am using
android/gradle.settings
jetifier=true
for Android compatibility? - [ ] I am using the NPM package
jetifier
for react-native compatibility?
android/build.gradle
:
// N/A
android/app/build.gradle
:
// N/A
android/settings.gradle
:
// N/A
MainApplication.java
:
// N/A
AndroidManifest.xml
:
<!-- N/A -->
Environment
Click To Expand
react-native info
output:
OUTPUT GOES HERE
-
Platform that you're experiencing the issue on:
- [ ] iOS
- [ ] Android
- [ ] iOS but have not tested behavior on Android
- [x] Android but have not tested behavior on iOS
- [ ] Both
-
react-native-firebase
version you're using that has this issue:- 13.1.0
- 12.1.0
-
Firebase
module(s) you're using that has the issue:- database
-
Are you using
TypeScript
?- N
- 👉 Check out
React Native Firebase
andInvertase
on Twitter for updates on the library.
Interesting - nice work pointing it out via code, looks like a reasonably easy transfer to an e2e test to probe it with assertions and see the failure, the e2e tests do have access to a primary and secondary app for config + testing
both apps demonstrated usage https://github.com/invertase/react-native-firebase/blob/6a1125cad1bb79a169ca073cb7ddc12b467cc7ef/packages/database/e2e/database.e2e.js#L27-L33
example (among others) of probing child_removed events https://github.com/invertase/react-native-firebase/blob/6a1125cad1bb79a169ca073cb7ddc12b467cc7ef/packages/database/e2e/query/on.e2e.js#L196
First step is to make a test that fails (most of the work done via your sample combined with links here) then trace through while that code is "hot" (usually by making the test it.only
so it's really focused) and usually the error is either very obvious, or it's in the native platform 😅
I won't have time to do this transform to test then examine for a while unfortunately, but that's the most efficient path forward if you have time to dig deeper
thank you, sorry it took me some time to make the tests run. So I did a small change based on your advice , but I was just getting an error from the test helpers. I think I am missing something
it.only('subscribe to child removed events', async function () {
const successCallback = sinon.spy();
const cancelCallback = sinon.spy();
const ref = firebase.database().ref(`${TEST_PATH}/childRemoved`);
const ref2 = firebase
.database(firebase.app('secondaryFromNative'))
.ref(`${TEST_PATH}/childRemoved`);
ref2.off('child_removed');
const child = ref.child('removeme');
await child.set('foo');
ref.on(
'child_removed',
$ => {
successCallback($.val());
},
() => {
cancelCallback();
},
);
await child.remove();
await Utils.spyToBeCalledOnceAsync(successCallback, 5000);
ref.off('child_removed');
successCallback.getCall(0).args[0].should.equal('foo');
cancelCallback.should.be.callCount(0);
});
Error :
moataz@moataz:~/Desktop/react-native-firebase$ yarn tests:android:test
yarn run v1.22.10
$ cd tests && ./node_modules/.bin/detox test --configuration android.emu.debug
detox[27098] INFO: [test.js] mocha --config e2e/.mocharc.js --configuration android.emu.debug --grep :ios: --invert --use-custom-logger true e2e
detox[27110] INFO: at node_modules/jet/lib/node/vm.js:78:11
[✈️] debugger has connected! Downloading app JS bundle...
detox[27110] INFO: at node_modules/jet/lib/node/console.js:16:15
Mapping auth host "localhost" to "10.0.2.2" for android emulators. Use real IP on real devices. You can bypass this behaviour with "android_bypass_emulator_url_remap" flag.
detox[27110] INFO: at node_modules/jet/lib/node/console.js:16:15
Mapping firestore host to "10.0.2.2" for android emulators. Use real IP on real devices. You can bypass this behaviour with "android_bypass_emulator_url_remap" flag.
detox[27110] INFO: at node_modules/jet/lib/node/console.js:16:15
Mapping storage host to "10.0.2.2" for android emulators. Use real IP on real devices.
database().ref().on()
detox[27110] INFO: at node_modules/jet/lib/node/console.js:16:15
Running "testing" with {"rootTag":11}
detox[27110] INFO: at e2e/init.js:40:15
detox[27110] WARN: at e2e/init.js:41:15
⚠️ A test failed:
detox[27110] WARN: at e2e/init.js:42:15
️ -> subscribe to child removed events
detox[27110] WARN: at e2e/init.js:49:13
️ -> Retrying in 5 seconds ... (1)
1) subscribe to child removed events
detox[27110] INFO: at e2e/init.js:55:11
✨ Tests Complete ✨
detox[27110] INFO: at e2e/init.js:77:15
Coverage data downloaded to: ./android/app/build/output/coverage//emulator_coverage.ec
0 passing (33s)
1 failing
1) database().ref().on()
subscribe to child removed events:
Error: Spy was not called within timeout period.
at Timeout._onTimeout (/home/moataz/Desktop/react-native-firebase/tests/node_modules/@react-native-firebase/private-tests-helpers/lib/index.js:3:824)
at listOnTimeout (node:internal/timers:557:17)
at processTimers (node:internal/timers:500:7)
detox[27098] ERROR: [cli.js] Command failed: mocha --config e2e/.mocharc.js --configuration android.emu.debug --grep :ios: --invert --use-custom-logger true e2e
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Btw I tried the same code in the issue with firebase js sdk and it is working fine
Oh that's fantastic that you have this open on your workbench. It can be a bit of a pain to get it all set up but there's nothing like a reproducible / automated test. You might just need to delay the check for the spy call? Sometimes the RTDB is slow, here's an example:
https://github.com/invertase/react-native-firebase/blob/6a1125cad1bb79a169ca073cb7ddc12b467cc7ef/packages/database/e2e/query/once.e2e.js#L125
Sadly I find it be a little flakier on the android emulator than iOS, so I prefer using iOS to develop against RTDB for listener stuff, however, that runs up against a second flaky issue we're having which is that Detox v18+ has a really nasty crash bug that kills the app maybe 20-40% of the time, making that not fun at the moment.
So I think adding a longer sleep would help ?
sorry even when putting a longer sleep I was still getting the same error
await Utils.spyToBeCalledOnceAsync(callback, 100000);
also I couldn't make tests run on ios 😅
Hello 👋, to help manage issues we automatically close stale issues. This issue has been automatically marked as stale because it has not had activity for quite some time. Has this issue been fixed, or does it still require the community's attention?
This issue will be closed in 15 days if no further activity occurs. Thank you for your contributions.
Hello 👋, to help manage issues we automatically close stale issues.
This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?
This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.
This one is perhaps still an issue and has what appears to be a reproduction
Hello 👋, to help manage issues we automatically close stale issues.
This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?
This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.