AngularFire recently changed the currentUser() method to return a promise. This means if you want to use the output of that promise in a call that returns an observable, such as doc('users/' + userId).get() you need to do a bit of work. One option is to keep everything promise based and go with:
async getAccountInformation(): Promise {
let userid = null;
await this.afAuth.currentUser.then(user => {
userid = user.uid;
});
return this.db.doc(`users/${userid}`).get().pipe(
map(doc => {
return doc.data();
})
).toPromise();
}
The toPromise()at the end of the observable does just that and allows us to do everything as a promise.
But, this feels a bit dated now we have RxJs and I’m not a fan the async/await syntax (not so say I never use it). So instead we can do the following:
getAccountInformation(): Observable {
return from(this.afAuth.currentUser.then(user => {
return user.uid;
})).pipe(switchMap(userid => {
return this.db.doc(`users/${userid}`).get().pipe(
map(doc => {
return doc.data();
})
);
}));
}
By wrapping the promise in from()we can convert it to an observable and then use the switchMap operator to move from one observable (currentuser) into the next (doc().get()). Without switchMap you would need to subscribe inside your first subscription in the calling file, not as clean at all.
Given that currentUser isn’t a stream that is likely to change that often it doesn’t really need to be an observable however it’s a good example for demonstration purposes.
Remember, all the same observable rules apply, the rest of the chain won’t execute until you do something with the result of your subscription and you might want to consider looking in to defer()to delay the execution of the promise also.