Angular Firestore:使用where子句的集合查询的正确语法是什么? [英] Angular Firestore: What is the correct syntax for a collection query that uses a where clause?

查看:62
本文介绍了Angular Firestore:使用where子句的集合查询的正确语法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有查询Firestore并返回 ImageUploadWId [] 类型的Observable的工作代码.我想返回一个 Promise .这是因为

I have working code that queries Firestore and returns an Observable of type ImageUploadWId[]. I would like to return a Promise instead. This is because

  1. 我的数据不经常更改;
  2. 我正在根据传入的数据执行删除.

SnapshotChanges()返回操作数组.第一个动作包含大小为1的不完整数组.最后一个动作包含大小为4的数组.它具有一个 groupId 中的所有 ImageUploadWIds .

SnapshotChanges() returns an array of actions. The first action contains an incomplete array of size 1. The last action contains an array of size 4. The last array is complete; it has all the ImageUploadWIds from the one groupId.

我只需要一个数组,该数组仅具有来自指定groupId的 ImageUploadWIds .使用Promise可以给我所有 groupIds ImageUploadWIds .我相信where子句不起作用.

I want just one array that has the ImageUploadWIds from only the designated groupId. Using a Promise is giving me the ImageUploadWIds from all the groupIds. I believe the where clause isn't working.

这是我的工作代码,它仅从一个groupId打印 imageUpload groupIds,但返回多个数组.最后一个数组是我唯一需要的一个.编辑(添加的日志语句):

Here is my working code, which only prints imageUploadgroupIds from one groupId, but returns more than one array. The last array is the only one I need. Edit (added log statements):

getImageInfosWIds(bathroomGroupId: string): Observable<ImageUploadWId[]> {
  return this.afs.collection(this.bathroomImagesLocation,
    ref => ref.where('groupId', '==', bathroomGroupId)).snapshotChanges()
    .map(actions => {
      return actions.map(a => {
        const data = a.payload.doc.data();
        const id = a.payload.doc.id;
        const imageUpload = new ImageUploadWId();
        imageUpload.set(id, <ImageUpload>data);
        return imageUpload;
      })
    })
}

onDeleteGroup(groupId: string) {
this.bathroomGroupService.getImageInfosWIds(groupId)
  .subscribe((imageUploads) => {
    console.log("imageUploads.length: " + imageUploads.length);
    for (let imageUpload of imageUploads) {
      console.log("(groupId, filename): (" + imageUpload.groupId + ", " + imageUpload.filename + ")");
    }
  })
}

这是我的代码尝试使用Promise.这将从我的两个组中打印imageUploads,而不是从给定的bathroomGroupId中打印.

Here is my code trying to use a Promise. This prints imageUploads from both of my groups instead of only from the given bathroomGroupId.

getImageInfosWIds(bathroomGroupId: string): Promise<QuerySnapshot> {
  return this.afs.collection(this.bathroomImagesLocation,
    ref => ref.where("groupId", "==", bathroomGroupId))
    .ref
    .get();
}

onDeleteGroup(groupId: string) {
  this.bathroomGroupService.getImageInfosWIds(groupId)
  .then( (querySnapshot) => {
      querySnapshot.forEach((doc) => {
        console.log("edit-bathrooms: " + doc.data().groupId);
      })
  },
  () => {console.log("Error in edit-bathrooms. promise unfullfilled " +
      "in onDeleteGroup( " + groupId + " )")});
}

这是有效的最终代码:

  onDeleteGroup(groupId: string) {
    this.bathroomGroupService.getImageInfosWIdsObservable(groupId)
    .pipe(take(1)).subscribe(
    data => {
      console.log(data[0].groupId);
    });
  }

 getImageInfosWIdsObservable(bathroomGroupId: string) {
   return this.afs.collection(this.bathroomImagesLocation,
   ref => ref.where('groupId', '==', bathroomGroupId)).snapshotChanges() //rxjs 5 -> 6  library
   .pipe(
    map(actions => actions.map(a => {
      const data = a.payload.doc.data();
      const documentId = a.payload.doc.id;
      const imageUpload = new ImageUploadWId();
      imageUpload.set(documentId, <ImageUpload>data);
      return imageUpload;
    }))
  );
}

最后一个单词.如果仍然有多余的数组,则可能是在代码的另一部分预订了相同的Firestore集合,而不是取消订阅.那是我问题的一部分.

Just one final word. If you're still getting an extra array, you may have subscribed to the same Firestore collection in another part of your code and not unsubscribed. That was part of my problem.

推荐答案

AngularFire2封装了Firebase引用,因此调用 .ref.get()会创建一个新引用,并忽略您提供的查询功能.

AngularFire2 wraps the Firebase reference, so calling .ref.get() creates a new reference and ignores the query function you supplied.

幸运的是,RxJS使得将Observable转换为Promise很容易.您只需要管道输入 first() take(1)即可强制完成Observable(否则,由于Firebase提供了无尽的实时流,因此承诺将永远无法解决).

Luckily, RxJS makes it easy to convert an Observable to a Promise. You just need to pipe in first() or take(1) to force the Observable to complete (otherwise the promise will never resolve because Firebase provides an endless realtime stream).

 return this.afs.collection(...)
  .valueChanges()
  .pipe(first())
  .toPromise()

这篇关于Angular Firestore:使用where子句的集合查询的正确语法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆