【问题标题】:Angular Fire fetching related data from same collectionAngular Fire 从同一集合中获取相关数据
【发布时间】:2020-11-06 14:02:11
【问题描述】:

我的 firestore 项目查询时遇到了一个奇怪的行为。项目的一位用户就像系统的所有者,我们称他为生产者。而另一个users,可以属于一个producer,所以我有一个users的集合,其中我有一个名为producer的字段,带有producer ID,如下所示。

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

*将生产者翻译成生产者。

我有一个称为转账的功能,我可以将现金从一个用户帐户转移到另一个帐户,但仅限于同一生产者的用户内部。所以我需要获取生产者与登录用户相同的所有用户,在这个集合上,这是我的功能:

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()
    })
  )
}

但它不起作用,结果上唯一的用户是调用函数的用户。这是 Angular Fire 的限制还是我做错了?

我认为这可能是一个错误,因为我可以使用 get on document 然后 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
            })
       )

这样,它返回生产者 produtor 与登录用户相同的所有用户。如果有人能解释一下原因,我将不胜感激。

【问题讨论】:

  • 您能展示一下您的数据库结构吗?我的假设是您没有查询正确的数据,因此没有获得某个 producer 下的 users。如果您的数据如下所示:生产者 -> 生产者 -> 用户 -> 用户 {id 和生产者字段},您可能需要查询 生产者 集合以检索正确的 生产者 文档,您可以访问其用户列表。
  • @sllopis 我刚刚添加了我的数据结构,我放了两条记录,一条 UID 以'06'开头的记录是生产者,其他用户与他相关,在字段produtor

标签: angular firebase google-cloud-firestore angularfire5


【解决方案1】:

看起来您的 OR 查询逻辑不正确。

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

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

事实上,您似乎根本不需要 OR 条件。为什么user.producer会被设置为两种不同的类型?

ie:如果 user.producer 始终设置为生产者 ID,那么您可以:

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

【讨论】:

  • 其实这个OR的条件是因为登录的用户可能是生产者本身,那么producerwouldn´t字段就是这个文档,但是,我会改变它,把现场进行测试。但它在查询时只返回一条记录,即已登录的用户。
【解决方案2】:

当你在 Angular Fire 中调用 .valueChanges() 时,它会返回一个 observable。

Observables 开辟了一个连续的通信渠道,随着时间的推移可以发出多个数据值。

所以我们需要从 Observable 中获取一个值,为此我们需要订阅它。 您可以使用 for valueChanges 调用文档并附加一个 pipe(take(1)),如下所示,但 get() 非常方便。

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

如果您需要任何进一步的说明,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-09
    • 2014-07-16
    • 2022-11-06
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    相关资源
    最近更新 更多