[英]Angular/Firestore Collection Document Query to return a single document field from all documents into an array
I am performing a query on my collection documents and trying to return just all phone numbers into an array.我正在对我的集合文档执行查询,并尝试将所有电话号码返回到一个数组中。 I just want to set the phone numbers into array for use by another function.
我只想将电话号码设置为数组以供另一个 function 使用。 Firebase docs only show a console log for (doc.id) and (doc.data) and no practical use for any other objects in your documents.
Firebase 文档仅显示 (doc.id) 和 (doc.data) 的控制台日志,对文档中的任何其他对象没有实际用途。 My console log for info.phoneNumbers returns all the phoneNumbers.
我的 info.phoneNumbers 控制台日志返回所有 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;
})
}```
Firestore is a "document store database". Firestore 是一个“文档存储数据库”。 You fetch and store entire DOCUMENTS (think "JSON objects") at a time.
您一次获取并存储整个 DOCUMENTS(想想“JSON 对象”)。 One of the "anti-patterns" when using document store databases is thinking of them in SQL/relational DB terms.
使用文档存储数据库时的“反模式”之一是以 SQL/关系数据库术语来考虑它们。 In SQL/relational DB, you "normalize" data.
在 SQL/关系数据库中,您“规范化”数据。 But in a document store database (a "NoSQL" database) we explicitly denormalize data -- that is, we duplicate data -- across documents on write operations.
但是在文档存储数据库(“NoSQL”数据库)中,我们显式地对数据进行非规范化——也就是说,我们在写操作时跨文档复制数据。 This way, when you fetch a document, it has all the data you need for its use cases.
这样,当您获取一个文档时,它就会包含您使用案例所需的所有数据。 You typically want to avoid "JOINs" and limit the number of references/keys in your data model.
您通常希望避免“JOIN”并限制数据 model 中的引用/键的数量。
What you are showing in the code above is valid in terms of fetching documents, and extracting the phoneNumber
field from each.您在上面的代码中显示的内容在获取文档和从每个文档中提取
phoneNumber
字段方面是有效的。 However, use of .forEach()
is likely not what you want.但是,使用
.forEach()
可能不是您想要的。 forEach()
iterates over the given array and runs a function, but the return value of forEach()
is undefined
. forEach()
遍历给定数组并运行 function,但forEach()
的返回值是undefined
。 So the return info.phoneNumber
in your code is not actually doing anything.因此,您代码中的
return info.phoneNumber
实际上并没有做任何事情。
You might instead use .map()
where the return value of the map() function is a new array, containing one entry for each entry of the original array, and the value of that new array is the return value from map()'s callback parameter.您可以改为使用
.map()
,其中 map() function 的返回值是一个新数组,其中原始数组的每个条目都包含一个条目,并且该新数组的值是 map()' 的返回值s 回调参数。
Also, mixing await
and .then()/.catch()
is usually not a good idea.此外,混合
await
和.then()/.catch()
通常不是一个好主意。 It typically leads to unexpected outcomes.它通常会导致意想不到的结果。 I try to use
await
and try/catch
, and avoid .then()/.catch()
as much as possible.我尝试使用
await
和try/catch
,并尽可能避免使用.then()/.catch()
。
So I would go with something like:所以我会 go 类似:
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;
});
I solved this with help and I hope this may be helpful to others in Getting access to 1 particular field in your documents.我在帮助下解决了这个问题,我希望这可能对其他人在获取对文档中 1 个特定字段的访问权时有所帮助。 In my service:
在我的服务中:
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
});
}
In my Component using typescript在我使用 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);
});
}
This returns all the phone numbers in a comma separated array.这将返回逗号分隔数组中的所有电话号码。
In my template I pull the numbers into an input for another function to send multiple text.在我的模板中,我将数字拉入另一个 function 的输入以发送多个文本。 Code in the template is not polished yet for the form, I am just getting it there for now.
模板中的代码还没有针对表单进行完善,我现在只是在那里。
<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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.