【问题标题】:AngularFire collection observable in NX Workspace triggered twiceNX Workspace 中可观察的 AngularFire 集合触发了两次
【发布时间】:2026-02-10 16:40:02
【问题描述】:

我有一个使用 @angular/fire (6.1.4) 和 NX 工作区的 Angular (v 11.1.1) 项目。 我注意到对集合的查询在调用时会返回两次数据。如果我使用take(1) 它只返回一次,但这会完成流并且不会再发生数据库更新,因此这不是我想要的。

在所涉及的代码下方。

数据库服务(db)

import { AngularFirestore } from '@angular/fire/firestore';
import firebase from 'firebase/app';
  
@Injectable({
  providedIn: 'root',  // Provided in the ROOT Injector 
})
export class DbService {

  constructor(private firestoreRef: AngularFirestore) {

// Here just for TEST purposes, just to isolate irrelevant code (eg. component)

// This is triggered twice
firestoreRef.collection('places')
            .valueChanges()
            .subscribe(p => console.log('GOT DATA DIRECT'));
}

我想在共享库中保留通用数据库服务,因为我想从 NX 工作区中的其他应用程序中重用它。想法是传递特定于项目的新 Firestore 密钥。

为此,我在共享库中创建了一个“数据访问层”模块,并将该模块导入app.module.ts

@NgModule({
  imports: [
    AngularFireModule.initializeApp(FirebaseConfigService.data),
    AngularFirestoreModule.enablePersistence(),
    AngularFireAuthModule
  ],
  providers: [FirebaseConfigService]
})
export class SharedDataAccessModule {
  static forRoot(data: FirebaseKeysModel): ModuleWithProviders<SharedDataAccessModule> {
    return {
      ngModule: SharedDataAccessModule,
      providers: [
        FirebaseConfigService,
        {
          provide: APP_INITIALIZER,
          multi: true,
          useFactory: (firebaseConfig: FirebaseConfigService) => () => {
            firebaseConfig.setFirebaseConfig(data);
          },
          deps: [FirebaseConfigService]
        }
      ]
    };
  }
}

FirebaseConfig 服务:

export class FirebaseConfigService {
  static data = {
    apiKey: '',
    authDomain: '',
    databaseURL: '',
    projectId: ''
  };

  setFirebaseConfig(moduleConfig: FirebaseKeysModel) {
    return new Promise<void>((resolve, reject) => {
      FirebaseConfigService.data.projectId = moduleConfig.projectId;
      FirebaseConfigService.data.apiKey = moduleConfig.apiKey;
      FirebaseConfigService.data.authDomain = moduleConfig.authDomain;
      FirebaseConfigService.data.databaseURL = moduleConfig.databaseURL;
    });
  }
}

这允许我在应用程序级别(在 app.module 中)传递特定的数据库键:

@NgModule({
  declarations: [AppComponent, NavigationComponent],
  imports: [
    ...
    // These are App specific keys for the DB
    SharedDataAccessModule.forRoot(environment.firebaseConfig),
  bootstrap: [AppComponent],
})
export class AppModule {}

【问题讨论】:

    标签: angular observable angularfire2 nrwl-nx


    【解决方案1】:

    我发现这是使用离线持久性时 Firestore 的预期行为(感谢 Frank van Puffelen):

    当您为快照附加监听器时,它会立即触发数据的本地状态(如果有)。然后它会检查服务器,这可能需要一些时间,如果服务器的状态与本地缓存不同(或者您已请求调用元数据更改),则再次使用来自服务器的状态触发。

    【讨论】: