A common requirement in any app is to determine if the current user is logged-in. Or you might want to check if a database record exists before performing some logic. Doing this in an elegant want throughout your AngularFire2 app is not always obvious.
While we could use RxJS, I find it much easier to handle these situations with Promises because they are NOT streams, but rather simple one-off operations.
Get the Current User
Converting an Observable to a Promise requires a completed signal from the stream. The AngularFire auth state will not complete automatically, so we pipe in the first
operator to kill it after the first emitted value.
Promise-Based Solution
If prefer this approach for the elegant async/await syntax.
import { first } from 'rxjs/operators';
isLoggedIn() {
return this.afAuth.authState.pipe(first()).toPromise();
}
async doSomething() {
const user = await isLoggedIn()
if (user) {
// do something
} else {
// do something else
}
}
Observable-Based Solution
Here’s the equivalent with an Observable. Not quite as elegant, especially when you need to perform this logic frequently,
import { first, tap } from 'rxjs/operators';
isLoggedIn() {
return this.afAuth.authState.pipe(first())
}
doSomething() {
isLoggedIn().pipe(
tap(user => {
if (user) {
// do something
} else {
// do something else
}
})
)
.subscribe()
}
Check if a Firestore Document Exists
We can use a similar helper to determine if a certain Firestore document exists.
docExists(path: string) {
return this.afs.doc(path).valueChanges().pipe(first()).toPromise()
}
Let’s say we want to find or create a document.
async findOrCreate(path: string, data: any) {
const doc = await docExists(path);
if (doc) {
return 'doc exists'
} else {
await this.afs.doc(path).set(data)
return 'created new doc'
}
}
Questions?
Ask questions via GitHub below OR chat on Slack #questions