I'm running firebase.init() in the first major component that loads. This component checks if the user is logged in and redirects appropriately - all good till this point.
Now if I "back" out of the app (Android device used for testing), and try to launch the app again, I get the error "Error: Uncaught (in promise): Firebase already initialized".
Is there a way to resolve this? Maybe by destroying the firebase instance when the user exits the app? Or check if firebase is initialized and reuse the existing instance?
Thanks!
My package.json
"nativescript-plugin-firebase": "^6.1.1",
"nativescript-angular": "6.0.0",
"nativescript-angular-cli": "0.1.9",
"tns-core-modules": "4.2.0-2018-06-29-01",
@EddyVerbruggen if possible, I'd really appreciate any pointers that you could share here, as it is holding up a deploy of our app
Thanks!
There are probably many ways to fix it - just make sure that code runs only once during your app's lifetime. Move it to a different component for instance, but without sharing a repo I can't go beyond some generic remarks like these.
Thanks, I'll try this and share a repo if it doesn't work.
On Tue, Oct 9, 2018, 12:36 AM Eddy Verbruggen notifications@github.com
wrote:
There are probably many ways to fix it - just make sure that code runs
only once during your app's lifetime. Move it to a different component for
instance, but without sharing a repo I can't go beyond some generic remarks
like these.—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/EddyVerbruggen/nativescript-plugin-firebase/issues/944#issuecomment-427946092,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABWqJPcWwgtqIkct-hR4rKZAfq0h1D9Tks5ui6IagaJpZM4XGkfr
.
Not totally sure if this is the way to go about it, but it worked, so sharing here:
Listen to the application's exit event, details here
During the exitEvent, kill the process (@EddyVerbruggen's Stackoverflow answer):
android.os.Process.killProcess(android.os.Process.myPid());
When you press back to exit the app, the process gets killed, and on launching again, firebase gets initiated afresh, avoiding this error.
@edusperoni thanks for the links. I did this, seems to work great. Just have a property you set if you should init firebase.
export class AppComponent implements OnInit {
shouldFireBaseInit: boolean = true;
constructor()
{
}
ngOnInit(): void {
//Called after the constructor, initializing input properties, and the first call to ngOnChanges.
//Add 'implements OnInit' to the class.
// Subscribe to begin listening for async result
applicationOn(launchEvent, (args: ApplicationEventData) => {
if (args.android) {
// For Android applications, args.android is an android.content.Intent class.
console.log("Launched Android application with the following intent: " + args.android + ".");
} else if (args.ios !== undefined) {
// For iOS applications, args.ios is NSDictionary (launchOptions).
console.log("Launched iOS application with options: " + args.ios);
}
});
applicationOn(suspendEvent, (args: ApplicationEventData) => {
if (args.android) {
// For Android applications, args.android is an android activity class.
console.log("SUSPEND Activity: " + args.android);
} else if (args.ios) {
// For iOS applications, args.ios is UIApplication.
console.log("UIApplication: " + args.ios);
}
});
applicationOn(resumeEvent, (args: ApplicationEventData) => {
if (args.android) {
// For Android applications, args.android is an android activity class.
console.log("RESUMEVENT Activity: " + args.android);
// set this to false
this.shouldFireBaseInit = false;
} else if (args.ios) {
// probably add it here as well for ios
// For iOS applications, args.ios is UIApplication.
console.log("UIApplication: " + args.ios);
}
});
if(this.shouldFireBaseInit)
{
firebase.init({
onAuthStateChanged: (data) => { // optional but useful to immediately re-logon the user when he re-visits your app
console.log(data.loggedIn ? "Logged in to firebase" : "Logged out from firebase");
if (data.loggedIn) {
console.log('logged in stuff');
}
else
{
console.log('not logged in');
}
}
});
}
}
}
@mosesweb I think you @ the wrong person :P
To shed a light into this issue, it does seem that firebase keeps running (and initialized) after all of angular dies. This IS an issue as it may not bind the new event listeners if you call them on init (your this WILL NOT point to the current instance).
Turns out we never faced it before because I've always used the "addcallback" methods, like addOnMessageReceivedCallback, so we replace the callback before it's called by firebase. Perhaps @EddyVerbruggen can point to the correct approach to handling this? I couldn't find a way to "remove" the callbacks, or a way to check if firebase is initialized or not.
It also seems like ngOnDestroy is not even called after the app is closed via back button, so the best approach is probably a check for when firebase is already initialized and a quick replacement of the callbacks.
Maybe using WeakRef may also work on determining if firebase should call the callbacks or store the events until they are rebound
On a sidenote, nativescript-angular does not call ngOnDestroy when the app dies, but will soon (https://github.com/NativeScript/nativescript-angular/pull/1728) so we could remove the firebase callbacks when it's destroyed and add them again when needed. Otherwise we might need to implement our own global handler which queues events for when angular is ready to receive them.
Most helpful comment
@mosesweb I think you @ the wrong person :P
To shed a light into this issue, it does seem that firebase keeps running (and initialized) after all of angular dies. This IS an issue as it may not bind the new event listeners if you call them on init (your
thisWILL NOT point to the current instance).Turns out we never faced it before because I've always used the "addcallback" methods, like
addOnMessageReceivedCallback, so we replace the callback before it's called by firebase. Perhaps @EddyVerbruggen can point to the correct approach to handling this? I couldn't find a way to "remove" the callbacks, or a way to check if firebase is initialized or not.It also seems like ngOnDestroy is not even called after the app is closed via back button, so the best approach is probably a check for when firebase is already initialized and a quick replacement of the callbacks.
Maybe using WeakRef may also work on determining if firebase should call the callbacks or store the events until they are rebound
Edit:
On a sidenote, nativescript-angular does not call ngOnDestroy when the app dies, but will soon (https://github.com/NativeScript/nativescript-angular/pull/1728) so we could remove the firebase callbacks when it's destroyed and add them again when needed. Otherwise we might need to implement our own global handler which queues events for when angular is ready to receive them.