我正在使用Cloud Function向移动设备发送通知。我在Firestore db.taskDetails.aggregate([
{$unwind:"$counter_offer"},
{$match:{_id:ObjectId('5bfbc0f9ac2a73278459efc1')}},
{$sort:{"counter_offer.Counter_offer_Amount":1}},
{$unwind:"$counter_offer"},
{"$group" : {_id:"$_id",
counter_offer:{ $push: "$counter_offer" },
"task_name": { "$first": "$task_name"},
"task_status": { "$first": "$task_status"},
"task_location": { "$first": "$task_location"},
}}
]).pretty()
和clientDetail
中有两个集合。我在两个集合中都有clientPersonalDetail
相同,但是日期存储在clientID
中,名称存储在clientPersonal中。
看看:
clientDetail
这是我的完整代码:
ClientDetail -- startDate
-- clientID
.......
ClientPersonalDetail -- name
-- clientID
.........
} );
以上功能显示的是这样的对象
exports.sendDailyNotifications = functions.https.onRequest( (request, response) => {
var getApplicants = getApplicantList();
console.log('getApplicants', getApplicants);
cors(request, response, () => {
admin
.firestore()
.collection("clientDetails")
//.where("clientID", "==", "wOqkjYYz3t7qQzHJ1kgu")
.get()
.then(querySnapshot => {
const promises = [];
querySnapshot.forEach(doc => {
let clientObject = {};
clientObject.clientID = doc.data().clientID;
clientObject.monthlyInstallment = doc.data().monthlyInstallment;
promises.push(clientObject);
});
return Promise.all(promises);
}) //below code for notification
.then(results => {
response.send(results);
results.forEach(user => {
//sendNotification(user);
});
return "";
})
.catch(error => {
console.log(error);
response.status(500).send(error);
});
});
但是我需要在通知中不显示ClientID,所以我必须加入clientPersonal集合才能使用clientID来获取名称。 应该怎么办?
我如何创建另一个函数,该函数仅通过将clientID作为参数传递来返回名称,并等待它返回name。 有人可以帮忙吗??
答案 0 :(得分:1)
但是我需要在通知中不显示ClientID,所以我必须加入clientPersonal集合才能使用clientID来获取名称。应该怎么办?
不幸的是,Firestore中没有JOIN子句。 Firestore中的查询很浅。这意味着它们仅从运行查询的集合中获取项目。在单个查询中无法从两个顶级集合中获取文档。 Firestore不一次性支持跨不同集合的查询。单个查询只能使用单个集合中的文档属性。
如何创建另一个函数,该函数仅通过将clientID作为参数传递来返回名称,并等待它返回名称。
因此,我能想到的最简单的解决方案是首先查询数据库以获取clientID
。拥有此ID后,请在回调中进行另一个数据库调用,以便获得相应的名称。
另一种解决方案是将用户名添加为ClientDetail
下的新属性,以便您只能查询数据库一次。这种做法称为denormalization
,是Firebase的常见做法。如果您不熟悉NoQSL数据库,建议您观看此视频Denormalization is normal with the Firebase Database,以更好地理解。它用于Firebase实时数据库,但相同的规则适用于Cloud Firestore。
此外,在复制数据时,需要记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果您想更新/删除项目,则需要在它存在的每个位置进行。
答案 1 :(得分:1)
“更轻松”的解决方案可能是重复数据。这在NoSQL世界中很常见。
更准确地说,您将在ClientDetail
集合中的文档中添加客户端name
的价值。
答案 2 :(得分:1)
在这种情况下,您可以使用两个额外的功能来使代码清晰。一个将从集合function checkDateRange(startDate: string, endDate: string, fillDate: string): boolean {
if (fillDate > startDate && fillDate < endDate) {
const _fillDate = moment(fillDate).utc();
return _fillDate.isBetween(startDate, endDate, null, '[]');
}
return false;
}
中读取所有文档的函数,而不是获取所有字段,而是仅获取ClientDetail
。然后调用另一个函数,该函数将扫描集合ClientID
中的所有文档,并仅检索具有ClientID的部件。比较这两个是否匹配,然后在匹配的地方进行任何操作。
您可以参考Get started with Cloud Firestore文档,了解如何从Firestore创建,添加和加载文档。
您的ClientPersonalDetail
应该看起来像这样:
package,json
我自己做了一些编码,这是我的example code in GitHub。通过部署此功能,将扫描一个集合中的所有文档,并比较另一集合中的ClientID。当找到匹配项时,将记录一条消息,否则将记录一条与ID不匹配的消息。您可以使用此函数的工作原理,并在您的代码中使用它。