-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Firestore emulator calls Google APIs to check auth token #2656
Comments
This is interesting, it appears to be trigged by the fact that AngularFireAuth dynamically imports I wonder if when I don't actually see an easy way around this with the current API... If AngularFirestore was a lazy loading module I would pull in AngularFireAuth as an optional and ensure it was initialized first. Maybe AngularFirestore can inject the |
#2661) * Adding global instance caches to the modules, so they don't freak out when HMR is enabled (#2655). This takes on `globalThis` as a needed polyfill for many environments. * If injected settings for modules are changed after they are initialized you will receive a warning and the prior instance will be returned (ignoring the changes), this is especially important for HMR. If HMR is detected there will be an additional warning suggesting they do a full reload to see the changes. * Added a polyfill table and notes about why we version like we do * Adding more convoluted stuff to my sample app to flex AngularFire * Internal cleanup on AngularFireAnalytics * AngularFireAnalytics will now wait for UserTrackingService to detect the user before sending the screen_view event, if UserTrackingService has been provided * Adding a warning if the Auth Emulator is detected in conjunction with AngularFirestore and AngularFireDatabase as they will invalidate the emulated auth token before the dynamic import of `firebase/auth` is completed (#2656) * Warn if we absorbed an error keeping Firestore persistence from enabling * Logging sign_up and login events in UserTrackingService * Adding credential observer to AngularFireAuth
I've done the best I could with the current API, there's now a warning in the soon to be cut |
I am trying to work this around by importing "firebase/auth" from the very root of the application, but the issue remains. Any idea? if it can help anyone, for the time being, my workaround is this: // add provider in you AppModule
{
provide: APP_INITIALIZER,
multi: true,
useFactory: useEmulatorProvider,
}
function useEmulatorProvider() {
return () => {
if (isEmulator) {
const firebase = require('firebase/app').default;
firebase.auth().useEmulator(`http://localhost:9099`);
}
};
} |
The trouble is that no matter how you slice it, unless you initialize auth and firestore/database at the same time inline in your APP_INITIALIZER, the behavior is indeterminate. Does auth load first or database/firestore?... no way to control with the exiting API. I will be prioritizing the addition of a lazy version of Database/Firestore/Storage in the next AngularFire minor, I've been putting that off for way too long. Not only would a lazy versions reduce your main bundle size but I will be able to ensure that AngularFireAuth is initialized first, if it's been provided. |
Also I could see filing this as a bug with the Firebase JS SDK... if you initialize Database/Firestore with FWIW Storage doesn't seem to have the same problem. @Feiyang1 any thoughts? |
FYI @jhuleatt we're going to run into a similar issue with ReactFire and |
In thinking about it more, I consider this unexpected behavior on the JS SDK side and have filed an issue. |
Yeah, when I tried reproducing to isolate the cause, I didn't encounter the bug when using the vanilla SDK, so I figured this was about AngularFire and create the issue here. |
@jornetsimon yeah, it's a race condition. Since we're dynamically importing auth AngularFire is much more likely to see it. |
Hi all, I was having the same issue.
|
I think i found a better workaround, but you guys can be the judge of that. Just use this in the component.
|
@prodtos Where you added that code? I tried to add in main app.component.ts but I get this error: |
Also, I tried this: but still I get the same error. |
@WUKS87 you can try with something like: export function initializeApp(afAuth: AngularFireAuth): () => Promise<null> {
return () => {
return new Promise((resolve) => {
if (!environment.emulators) {
return resolve();
} else {
afAuth.useEmulator(`http://${location.hostname}:9099/`).then(() => {
resolve();
});
}
});
};
}
@NgModule({
...
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [AngularFireAuth],
useFactory: initializeApp
},
{ provide: USE_AUTH_EMULATOR, useValue: environment.emulators ? ['localhost', 9099] : undefined },
{ provide: USE_FIRESTORE_EMULATOR, useValue: environment.emulators ? ['localhost', 8080] : undefined },
{ provide: USE_FUNCTIONS_EMULATOR, useValue: environment.emulators ? ['localhost', 5001] : undefined },
],
bootstrap: [AppComponent]
})
export class AppModule {
} |
@newable Yup, works like a charm! Thanks man :) |
The solution provided by @newable works as long as you can make sure that What I resorted to was the following and it takes care of both issues.
The Firebase SDK initialization is not needed when Auth emulator is not being used, so in production builds the
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { FIREBASE_OPTIONS } from '@angular/fire';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { load as loadFirebaseConfig } from './firebase-fetch-config';
import { initialize as initializeFirebaseApp } from './firebase-init-app';
if (environment.production) {
enableProdMode();
}
loadFirebaseConfig()
.then((config) => {
initializeFirebaseApp(config);
return platformBrowserDynamic([
{
provide: FIREBASE_OPTIONS,
useValue: config,
},
]).bootstrapModule(AppModule);
})
.catch((err) => console.error(err));
import firebase from 'firebase';
import { environment } from './environments/environment';
export const initialize = (config: any) => {
firebase.initializeApp(config);
if (environment.firebase.emulators?.auth) {
firebase.auth().useEmulator(environment.firebase.emulators.auth);
}
};
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { AngularFireModule } from '@angular/fire';
import { AngularFireAuthModule } from '@angular/fire/auth';
import { AngularFirestoreModule, USE_EMULATOR as FIRESTORE_EMULATOR_CONFIGURATION } from '@angular/fire/firestore';
import { AppStoreModule } from '@app-store/app-store.module';
import { TranslocoRootModule } from '../transloco/transloco-root.module';
import { environment } from '../../environments/environment';
@NgModule({
declarations: [],
imports: [
CommonModule,
HttpClientModule,
TranslocoRootModule,
AppStoreModule,
AngularFireModule,
AngularFirestoreModule,
AngularFireAuthModule,
],
providers: [
{
provide: FIRESTORE_EMULATOR_CONFIGURATION,
useValue: environment.firebase.emulators?.firestore,
},
],
})
export class CoreModule {} |
@amilor's solution works perfectly and I am using ngrx... Thanks a lot! |
Version info
Angular:
10.2.0
Firebase:
8.0.1
AngularFire:
6.1.0-rc.3
How to reproduce these conditions
Failing test unit, Stackblitz demonstrating the problem
https://github.com/jornetsimon/af-auth-debug
Updated with commit reproducing the issue.
Steps to set up and reproduce
Sample data and security rules
Providers config:`
Debug output
When using emulators :
Expected behavior
The AngularFirestore service should target the emulator to verify the auth token.
Actual behavior
There is no problem when authenticating THEN navigating to a component using the AngularFirestore service.
But when loading the app directly through the firestore component endpoint, it seems like it doesn't have the time to be aware of the emulator config...
Note : The issue is the same with 6.1.0-rc.2 and 6.1.0-rc.3.
The text was updated successfully, but these errors were encountered: