node.js - 云函数查询冲突
问题描述
我正在编写一个谷歌云功能来创建聊天室,用户从移动应用程序向他的兴趣发送一个请求到 firestore,然后触发函数读取 firestore 中的所有待处理请求,直到找到与用户匹配的人。当发生这种情况时,云功能会删除两个请求并创建聊天室,但我的问题是,如果多个用户同时发送请求,云功能会读取理论上应该已经删除的请求。这是我的代码:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
exports.cargarPeticion = functions.firestore.document('/Requests/{id}').onCreate((snap, context) => {
const newValue = snap.data();
const uid = newValue.uid;
const age = newValue.age;
const sex = newValue.sex;
const manInterest = newValue.Hombres;
const womenInterest = newValue.Mujeres;
const loveInterest = newValue.Love;
const friendInterest = newValue.Friendship;
const timestamp = newValue.Timestamp;
const minAgeInterest = newValue.ageMin;
const maxAgeInterest = newValue.ageMax;
var ciclo = true;
db.collection('Requests').orderBy('Timestamp').get()
.then((snapshot) => {
try{
snapshot.forEach((doc) => {
var data = doc.data();
if(data.uid !== uid){
console.log("NUEVO");
console.log(doc.id, '=>', data.uid);
if(loveInterest === data.Love || friendInterest === data.Friendship){
if(data.age >= minAgeInterest &&
data.age <= maxAgeInterest &&
((sex === "H" && data.Hombres === "true") || (sex === "M" && data.Mujeres === "true"))){
if(age >= data.ageMin &&
age <= data.ageMax &&
((manInterest === "true" && data.sex === "H") || (womenInterest === "true" && data.sex === "M"))){
var arrayUsers = [uid, data.uid];
console.log("ID SALA");
console.log(uid.substring(0, 8) + data.uid.substring(0, 7) + doc.id.substring(0, 7));
db.collection('chatRoom').doc(uid.substring(0, 8) + data.uid.substring(0, 7) + doc.id.substring(0, 7)).set({
arrayUsers: arrayUsers,
uid1: uid,
uid2: data.uid,
chatRoomId : uid.substring(0, 8) + data.uid.substring(0, 7) + doc.id.substring(0, 7),
ultimoMensaje: '',
ultimoEscritorUid : '',
ultimoMensajeTiempo : 0
});
db.collection('Requests').doc(doc.id).delete();
db.collection('Requests').doc(snap.id).delete();
throw exception
}
}
}
}
});
}catch(exception){
console.log(exception);
}
return null;
})
.catch((err) => {
console.log('Error getting documents', err);
});
})
解决方案
为了防止并发数据库更新创建不一致的数据集,您需要使用事务来执行更新。使用事务时,允许第一个实例修改数据,任何对同一数据的冲突更新都会自动重试,直到没有冲突为止。
推荐阅读
- haskell - 使用 Haskell 的 Quickcheck 进行传递性的最佳测试
- java - 如何为 ioBuffer 分配和检索无符号 Long 值
- android - 菜单图标不显示
- python - 函数回调循环2次
- java - Java 高级套接字序列化
- azure - 在 Azure 中创建后等待机器人准备就绪
- scala - 在 main 方法中使用时找不到隐式
- python-3.x - Twilio 多个收件人
- c++ - 具有移动语义的 C++ 可变参数工厂导致运行时崩溃
- c# - MainWindow() 构造函数末尾的 System.Core.dll 中的 System.NullReferenceException (C# WPF)