Node.js 云功能和云Firestore用户关联功能
简单地说,假设我有一个云Firestore DB,我在其中存储一些用户数据,如电子邮件、地理位置数据(作为地理点)和其他一些东西。 在云函数中,我有一个“myFunc”,它运行时试图基于地理查询在两个用户之间“链接”两个用户(我使用GeoFirestore) 现在一切正常,但我不知道如何避免这种情况:Node.js 云功能和云Firestore用户关联功能,node.js,google-cloud-firestore,google-cloud-functions,Node.js,Google Cloud Firestore,Google Cloud Functions,简单地说,假设我有一个云Firestore DB,我在其中存储一些用户数据,如电子邮件、地理位置数据(作为地理点)和其他一些东西。 在云函数中,我有一个“myFunc”,它运行时试图基于地理查询在两个用户之间“链接”两个用户(我使用GeoFirestore) 现在一切正常,但我不知道如何避免这种情况: 用户A调用myFunc试图找到要关联的人,并找到用户B作为可能的人 同时,用户B也调用myFunc,试图找到一个要关联的人,但发现用户C是一个可能的人 在这种情况下,用户A将与用户B关联,但用
- 用户A调用myFunc试图找到要关联的人,并找到用户B作为可能的人
- 同时,用户B也调用myFunc,试图找到一个要关联的人,但发现用户C是一个可能的人
exports.myFunction = functions.region('europe-west1').https.onCall( async (data , context) => {
const userDoc = await firestore.collection('myCollection').doc(context.auth.token.email).get();
if (!userDoc.exists) {
return null;
}
const userData = userDoc.data();
if (userData.associated) { // IF THE USER HAS ALREADY BEEN ASSOCIATED
return null;
}
const latitude = userData.g.geopoint["latitude"];
const longitude = userData.g.geopoint["longitude"];
// Create a GeoQuery based on a location
const query = geocollection.near({ center: new firebase.firestore.GeoPoint(latitude, longitude), radius: userData.maxDistance });
// Get query (as Promise)
let otherUser = []; // ARRAY TO SAVE THE FIRST USER FOUND
query.get().then((value) => {
// CHECK EVERY USER DOC
value.docs.map((doc) => {
doc['data'] = doc['data']();
// IF THE USER HAS NOT BEEN ASSOCIATED YET
if (!doc['data'].associated) {
// SAVE ONLY THE FIRST USER FOUND
if (otherUser.length < 1) {
otherUser = doc['data'];
}
}
return null;
});
return value.docs;
}).catch(error => console.log("ERROR FOUND: ", error));
// HERE I HAVE TO RETURN AN .update() OF DATA ON 2 DOCUMENTS, IN ORDER TO UPDATE THE "associated" and the "userAssociated" FIELDS OF THE USER WHO WAS SEARCHING AND THE USER FOUND
return ........update({
associated: true,
userAssociated: otherUser.name
});
}); // END FUNCTION
exports.myFunction=functions.region('europe-west1').https.onCall(异步(数据、上下文)=>{
const userDoc=wait firestore.collection('myCollection').doc(context.auth.token.email).get();
如果(!userDoc.exists){
返回null;
}
const userData=userDoc.data();
if(userData.associated){//如果用户已经被关联
返回null;
}
常数纬度=用户数据.g.地理点[“纬度”];
常量经度=userData.g.geopoint[“经度”];
//基于位置创建地理查询
const query=geocollection.near({中心:new firebase.firestore.GeoPoint(纬度、经度),半径:userData.maxDistance});
//获取查询(作为承诺)
让otherUser=[];//数组保存找到的第一个用户
query.get().then((值)=>{
//检查每个用户文档
value.docs.map((doc)=>{
doc['data']=doc['data']();
//如果用户尚未关联
如果(!doc['data'].associated){
//仅保存找到的第一个用户
if(otherUser.length<1){
otherUser=doc['data'];
}
}
返回null;
});
返回值.docs;
}).catch(error=>console.log(“发现错误:”,error));
//在这里,我必须返回2个文档上的数据的.update(),以便更新正在搜索和找到的用户的“关联”和“用户关联”字段
返回……更新({
是的,
userAssociated:otherUser.name
});
}); // 端函数
您应该在云功能中使用。由于云函数在后端使用AdminSDK,因此云函数中的事务使用悲观并发控制
悲观事务使用数据库锁来防止其他操作修改数据
请参阅表单了解更多详细信息。特别是,您将看到:
在服务器客户端库中,事务将锁定
他们阅读的文件。事务对文档的锁定会阻止其他事务
来自的事务、批处理写入和非事务写入
更改该文档。事务在以下位置释放其文档锁:
承诺时间。如果超时或失败,它也会释放锁
任何理由
当事务锁定文档时,其他写入操作必须等待
使事务释放其锁。交易获得了它们的价值
按时间顺序锁
从您描述的内容来看,您似乎需要一个事务和/或安全规则。很难说得更具体一些,因为我不完全理解在实现这一点的过程中您遇到了什么困难。你有没有可能分享这个消息?嗨@FrankvanPuffelen,谢谢你的回答!我刚刚在我的问题中添加了我的代码,同时我正在阅读一些关于事务的文档,以查看它们是否符合我的需要。