简体   繁体   中英

Angular Fire fetching related data from same collection

I´m facing a strange behavior with a query on my firestore project. One user of the project is like the owner of the system, we call him the producer. And the other users , can belong to one producer , so I have a collection of users , where I have a field called producer , with the producer ID , like below.

{user: {id: '...', producer: '...', ...}

在此处输入图像描述 * Translate producer to produtor.

I have a functionality called a transfer, where I can transfer cash from one user account to another, but only within the users of the same producer. So I need to fetch all the users where the producer is the same as the logged user, on this collection, here is my function:

constructor(
  private afAuth: AngularFireAuth,
  private afs: AngularFirestore
) { }

fetchUsers() {
  return this.afAuth.authState.pipe(
    switchMap( user => { // Here I have the logged user
      return this.afs.doc(`users/${user.uid}`).valueChanges() // Here I need his details on users collection
    }),
    first(),
    switchMap( (user: any) => {
      return this.afs.collection('users',
        ref => ref.where('producer', '==', user.producer) // Now I want the other users from same producer
      ).valueChanges()
    })
  )
}

But it does not work, the only user on the result is the user calling the function. Is it a limitation of the Angular Fire or maybe I´m doing it in the wrong way?

I think it´s maybe a bug, because I could workaround this using get on document and then on collection:

return this.afAuth.authState.pipe(
            switchMap( user => {
                return this.afs.doc(`users/${user.uid}`).get()
            }),
            first(),
            map( usuario => {
                return usuario.data()
            }),
            switchMap( (usuario: any) => {
                return this.afs.collection('users', ref => ref.where('produtor', '==', usuario.produtor)).get()
            }),
            first(),
            map( data => {
                let users = []
                data.docs.map( doc => {
                    users.push(doc.data())
                })
                return users
            })
       )

This way, it returns all the users where the producer, produtor , is the same of logged in user. I´ll appreciate if someone could explain me why.

Looks like your OR query logic is incorrect.

return this.afs.collection('users',
        ref => ref.where('producer', 'in', [user.producer, user.uid]) 
).valueChanges()

https://firebase.google.com/docs/firestore/query-data/queries

In fact it appears you do not need an OR condition at all. Why would user.producer be set to two different types?

ie: if user.producer is always set to a producer ID, then you can have just:

return this.afs.collection('users',
            ref => ref.where('producer', '==', user.uid) 
    ).valueChanges()

When you call.valueChanges() in Angular Fire, it returns an observable.

Observables open up a continuous channel of communication in which multiple values of data can be emitted over time.

So we need to get a value from an Observable and for that we need to subscribe to it. You could call the document with for valueChanges and attach a pipe(take(1)) as following, but get() is pretty handy.

   this.afs.doc(`users/${user.uid}`).valueChanges()
   .pipe(take(1))
   .subscribe(v => {
       console.log(v);
    });

Please let me know if you need any further clarification.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM