Angular/Firestore 集合文档查询将所有文档中的单个文档字段返回到数组中

时间:2021-05-07 16:31:51

标签: arrays angular google-cloud-firestore

我正在对我的收藏文档执行查询,并试图将所有电话号码返回到一个数组中。我只想将电话号码设置为数组以供另一个功能使用。 Firebase 文档仅显示 (doc.id) 和 (doc.data) 的控制台日志,对文档中的任何其他对象没有实际用途。我的 info.phoneNumbers 控制台日志返回所有电话号码。

    async getPhone() {
    await this.afs.collection('members', ref => ref.where('phoneNumber', '>=', 0))
    .get().toPromise()
    .then(snapshot => {
      if (snapshot.empty) {
        console.log('No Matches');
        return;
      }
      this.getInfo(snapshot.docs);
      });
    }
    getInfo(data) {
      data.forEach(doc => {
        let info = doc.data();
        console.log(info.phoneNumber, 'Phonenumbers');
        // let myArray = [];
        // myArray.push(doc.doc.data());
        // const phoneNumber = info.phoneNumber as [];
        // console.log(myArray, 'ARRAY');
        return info.phoneNumber;
      })
  }```

2 个答案:

答案 0 :(得分:1)

Firestore 是一个“文档存储数据库”。您一次获取并存储整个文档(想想“JSON 对象”)。使用文档存储数据库时的“反模式”之一是在 SQL/关系数据库术语中考虑它们。在 SQL/关系数据库中,您“规范化”数据。但是在文档存储数据库(“NoSQL”数据库)中,我们明确地非规范化数据——也就是说,我们复制数据——跨文档写入操作。这样,当您获取一个文档时,它就拥有了其用例所需的所有数据。您通常希望避免“JOIN”并限制数据模型中的引用/键的数量。

您在上面的代码中显示的内容在获取文档和从每个文档中提取 phoneNumber 字段方面是有效的。但是,使用 .forEach() 可能不是您想要的。 forEach() 迭代给定数组并运行一个函数,但 forEach() 的返回值为 undefined。因此,您代码中的 return info.phoneNumber 实际上并没有做任何事情。

您可以改为使用 .map() ,其中 map() 函数的返回值是一个新数组,原始数组的每个条目都包含一个条目,该新数组的值是来自map() 的回调参数。

此外,将 await.then()/.catch() 混合通常不是一个好主意。它通常会导致意想不到的结果。我尝试使用 awaittry/catch,并尽可能避免使用 .then()/.catch()

所以我会选择类似的东西:

try {
  let querySnap = await this.afs.collection('members', ref => 
  ref.where('phoneNumber', '>=', 0)).get();

  let phoneNumbers = await this.getInfo(querySnap.docs[i].data());
} catch(ex) {
  console.error(`EXCEPTION: ${ex.message}`);
}

getInfo(querySnapDocs) {
    let arrayPhoneNumbers = querySnapDocs.map(docSnap => {
        let info = doc.data();
        let thePhoneNum = info.phoneNumber
        console.log(`thePhoneNum is: ${thePhoneNum}`);
        return thePhoneNum;
      });

    return arrayPhoneNumbers;
  });

答案 1 :(得分:0)

我在帮助下解决了这个问题,我希望这可能对其他人在获取文档中的 1 个特定字段的访问权方面有所帮助。在我的服务中:

async getPhone() {
    return await this.afs.collection('members', ref => ref.where('phoneNumber', '>=', 0))
    .get().toPromise()
    .then(snapshot => {
      if (snapshot.empty) {
        console.log('No Matches');
        return;
      }
      return this.getInfoNum(snapshot.docs);
      });
    }
    getInfoNum(data) {
      return data.map(doc => {
        let info = doc.data();
        return info.phoneNumber
      });
  }

在我的组件中使用 typescript

phoneNumbers: string[] = [];

getPhone() {
    this.dbService.getPhone().then(phoneNumbers => {
      this.phoneNumbers = phoneNumbers;
      this.smsGroupForm.controls.number.setValue(phoneNumbers.join(',')) //sets array seperated by commas
      console.log(phoneNumbers);
    });
  }

这将返回逗号分隔数组中的所有电话号码。

在我的模板中,我将数字拉入另一个函数的输入中以发送多个文本。模板中的代码尚未针对表单进行完善,我现在只是在那里。

 <ion-list>
       <ion-item *ngFor="let phoneNumber of phoneNumbers">
       <ion-label position="floating">Phone Number</ion-label>
       <ion-input inputmode="number" 
        placeholder="Phone Number" 
        formControlName="number"
        type="number">{{ phoneNumber }}
       </ion-input>
       </ion-item>  
  </ion-list>
相关问题