Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Error: Uncaught (in promise): Firebase already initialized #944

Closed
suparnavg opened this issue Oct 3, 2018 · 6 comments
Closed

Error: Uncaught (in promise): Firebase already initialized #944

suparnavg opened this issue Oct 3, 2018 · 6 comments

Comments

@suparnavg
Copy link

suparnavg commented Oct 3, 2018

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",
@suparnavg
Copy link
Author

@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!

@EddyVerbruggen
Copy link
Owner

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.

@suparnavg
Copy link
Author

suparnavg commented Oct 8, 2018 via email

@suparnavg
Copy link
Author

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.

@mosesweb
Copy link

mosesweb commented Feb 15, 2019

@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');
      }
      }
    });
}
  }
  
}

@edusperoni
Copy link
Contributor

edusperoni commented Feb 19, 2019

@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

Edit:

On a sidenote, nativescript-angular does not call ngOnDestroy when the app dies, but will soon (NativeScript/nativescript-angular#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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants