angular / angularfire

Angular + Firebase = ❤️
https://firebaseopensource.com/projects/angular/angularfire2
MIT License
7.68k stars 2.19k forks source link

HMR t v6.1.0 RC3: Firestore Emulators Error: Precondition failed #2655

Closed Meistercoach83 closed 3 years ago

Meistercoach83 commented 3 years ago

Hey there! I have a problem with firebase / angularfire2 (latest rc) and the cloud emulators. If I add this { provide: USE_FIRESTORE_EMULATOR, useValue: environment.useEmulators ? ['localhost', 8080] : undefined }, to my app.module, the routing (with guards) is not working any longer with the error message "NavigationError(id: 2, url: '/setup', error: FirebaseError: [code=failed-precondition]: Firestore has already been started and its settings can no longer be changed. You can only modify settings before calling any other methods on a Firestore object.) platform-browser.js:66 " Can anyone help me with that?

Version info

Angular: 11.0.0 Firebase: 8.16.1 AngularFire: latest RC 6.1.0-rc.3 Other (e.g. Ionic/Cordova, Node, browser, operating system): Angular CLI: 11.0.1 Node: 12.18.1 OS: win32 x64

jornetsimon commented 3 years ago

I'm getting this too. AFAIK this bug was introduced in 6.1.0 RC3. The important missing piece is that it only happens with HMR enabled (ng serve --hmr).

Stack trace indicates this has to do with redeclaring AngularFirestore :

Screen Shot 2020-11-16 at 08 31 49

You can reproduce by commenting any piece of code (except root styles) and let Webpack pick up the change.

@Meistercoach83 Maybe you could rename the issue with a more precise description

jamesdaniels commented 3 years ago

hmr would make sense, as firebase has side effects and angularfire is for the most part side-effect free. e.g, AngularFirestore doesn't keep a global cache of it's instantiated instances. Instead when it's initialized it merrily tries to create and initialize a new firestore instance.

There's two work arounds here IMO, A) keep a global cache for instantiated firestore instances B) inspect the settings/options on an instantiated instance & check that they match the passed in settings, else try to apply and error out if it fails. The benefit of B would be better guard rails incase someone tries to mess with DI to change firestore settings without creating a second app & you'd get a helpful error if you changed the DI with hmr on. I'll investigate that option today.

jamesdaniels commented 3 years ago

This should be resolved in 6.1.0.rc-4.

jamesdaniels commented 3 years ago

I added a globalThis cache of instantiated firebase SDK instances. It should ignore & warn if DI tokens change & will include an additional note if HMR is detected. Please report a new issue if you find any more problems with AngularFire and HMR, I've not had the chance to give it a spin.