Angular Firestore:使用where子句的集合查询的正确语法是什么?

时间:2018-05-17 00:56:02

标签: javascript angular firebase google-cloud-firestore

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

  1. 我的数据经常不变;
  2. 我正在根据进来的数据执行删除。
  3. SnapshotChanges()返回一系列操作。第一个操作包含一个大小为1的不完整数组。最后一个操作包含一个大小为4的数组。最后一个数组已完成;它包含ImageUploadWIds中的所有groupId

    我只想要一个只有指定groupId的ImageUploadWIds的数组。使用Promise会从ImageUploadWIds中获取groupIds。我相信where子句不起作用。

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

    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打印。

    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集合而未取消订阅。这是我问题的一部分。

2 个答案:

答案 0 :(得分:2)

AngularFire2包装Firebase引用,因此调用first()会创建一个新引用并忽略您提供的查询功能。

幸运的是,RxJS可以轻松地将Observable转换为Promise。您只需要在take(1) return this.afs.collection(...) .valueChanges() .pipe(first()) .toPromise() 中管道以强制Observable完成(否则承诺永远不会解决,因为Firebase提供了无限的实时流)。

      cn.Open();

      String dateFormat = "MM/dd/yyyy";//The format that the txt_dob control uses
      DateTime parsedDate = DateTime.ParseExact(
      txtdob.Text, dateFormat, CultureInfo.InvariantCulture);

        cmd = new SqlCommand("INSERT INTO register ( DOB) VALUES(@DOB, cn);

        cmd.Parameters.AddWithValue("@DOB", txtdob.Text);
        cmd.ExecuteNonQuery();

      MessageBox.Show("saved")
      cn.Close();

答案 1 :(得分:0)

应该是,

return this._afs.collection(this.bathroomImagesLocation, x => x
            .where('groupId', '==',bathroomGroupId));