I'm using Angular 15 and @angular/fire ^7.5.0 for my project.
I have a service that makes some calls to the Firestore database, but before i perform any action i need to recover some information from the current user that is provided by FireAuth by an Observable.
import {
collection,
Firestore,
collectionData,
} from '@angular/fire/firestore';
import { AuthService } from '../auth/auth.service';
import { User } from '@angular/fire/auth';
export class DummyDataService {
userObservable: Observable<User | null>;
constructor(
private fs: Firestore,
private _auth: AuthService
) {
// currentUser$ is an Observable that holds the User data when available
this.userObservable = this._auth.currentUser$;
}
// example function
getAll() {
// this should be done after the user$ observable is filled with the real User
const coll = collection(this.fs, `/${user.custom_data}/dummydata`);
// return the data as an Observable
return collectionData(coll, { idField: 'id' });
}
}
So I'm asking which is the correct way to handle this kind of scenario
You can declare an observable that begins with the non-empty emission of userObservable, then map it accordingly:
export class DummyDataService {
userObservable: Observable<User | null>;
constructor(
private fs: Firestore,
private _auth: AuthService
) {
this.userObservable = this._auth.currentUser$;
}
getAll() {
return this.userObservable.pipe(
filter(user => !!user),
map(user => collection(this.fs, `/${user.custom_data}/dummydata`)),
switchMap(coll => collectionData(coll, { idField: 'id' }))
);
}
}
filter is used to prevent emissions where user is empty.map converts the user into the collectionswitchMap will emit the emissions from its inner source (collectionData(...))Note, if the method doesn't take a parameter, you don't need to use a method that returns an observable, you can simply declare the observable as a property:
export class DummyDataService {
constructor(
private fs: Firestore,
private _auth: AuthService
) { }
dummydata$ = this._auth.currentUser$.pipe(
filter(user => !!user),
map(user => collection(this.fs, `/${user.custom_data}/dummydata`)),
switchMap(coll => collectionData(coll, { idField: 'id' }))
);
}