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