Chaining Angular Firestore Collections
This is hard to explain but I'll do my best. I have a database structure setup in Firebase like this:
User (Firebase User)
Connection
- Group
- Role
UserDetails
- First Name
- Last Name
- Address
Basically what I am trying to do is get the current user using AngularFireAuth, then query the User Details collection by user.email, and then query the Connections collection by user.email. Finally, map all this out to a User model and store that in an observable.
EDIT:
I have figured out how to get the first collection to the user observable but not sure where to go from here.
this.user = this.afAuth.authState.pipe(
map(user => user.email),
flatMap(email => this.afs.collection<User>(this.userRef, res => res.where('email', '==', email)).valueChanges()),
mergeAll(),
first()
)
EDIT2:
So this is what I came up with and it's working BUT it just seems not right. I can tell there is a performance impact (albeit not that much). Probably won't ever use this for production but I'll continue using this solution as a proof of concept until I can find a better way.
this.user = this.afAuth.authState.pipe(
map(user => user.email),
concatMap(email => {
return zip(
this.afs.collection<Connection>('connections', res => res.where('email', '==', email)).snapshotChanges().pipe(mergeAll(), first()),
this.afs.collection<User>('users', res => res.where('email', '==', email)).snapshotChanges().pipe(mergeAll(), first())
)
}),
map(([connection, details]) => {
const a = connection.payload.doc.data() as Connection;
const b = details.payload.doc.data() as User;
return { ...a, ...b };
})
)
Answer
So after some research, I came up with this solution which does work. Probably not the best approach, but for a proof-of-concept project I am okay with it.
this.user = this.afAuth.authState.pipe(
map(user => user.email),
concatMap(email => {
return zip(
this.afs.collection<Connection>('connections', res => res.where('email', '==', email)).snapshotChanges().pipe(mergeAll(), first()),
this.afs.collection<User>('users', res => res.where('email', '==', email)).snapshotChanges().pipe(mergeAll(), first())
)
}),
map(([connection, details]) => {
const a = connection.payload.doc.data() as Connection;
const b = details.payload.doc.data() as User;
return { ...a, ...b };
})
)
Related Questions
- → Make a Laravel collection into angular array (octobercms)
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → Angularjs not working inside laravel form
- → Analysis of Flux implementations
- → how to write react component to construct HTML DOM
- → angular ng-repeat and images in a row
- → Conditional BG Color on AngularJS
- → Should I 'use strict' for every single javascript function I write?
- → getting the correct record in Angular with a json feed and passed data
- → "Undefined is not a function" at .toBe fucntion
- → angularjs data binding issue
- → Angular / JavaScript auto hydrate an instance
- → Convert generic text string in json object into valid url using Angular