我正在尝试设置一些用户数据,具体取决于我的USERS COLLECTION中已有的用户数量。这甚至包括一个userId,它应该是一个数字。
exports.setUserData = functions.firestore.document('/users/{documentId}')
.onCreate(event => {
return admin.firestore().collection('users')
.orderBy('userId', 'desc').limit(1)
.get().then(function(snapshot) {
const user = snapshot.docs[0].data();
var lastUserId = user.userId;
var userObject = {
userId: lastUserId + 1,... some other fields here
};
event.data.ref.set(userObject, {
merge: true
});
});
});
我在这里注意到的一个问题是,快速添加2个用户导致那些具有相同userId
的文档可能是因为get()
查询是异步的?
有没有办法让整个setUserData
方法同步?
答案 0 :(得分:2)
无法使云功能按顺序运行您的函数调用。这也与自动扩展到需求的无服务器承诺完全相反。
但是在你的情况下,有一个更简单,更低级别的原语来获得顺序ID。您应该将最后已知的用户ID存储在数据库中,然后use a transaction以读取/更新它。
var counterRef = admin.firestore().collection('counters').doc('userid');
return db.runTransaction(function(transaction) {
// This code may get re-run multiple times if there are conflicts.
return transaction.get(counterRef).then(function(counterDoc) {
var newValue = (counterDoc.data() || 0) + 1;
transaction.update(counterRef, newValue);
});
});
<强>解决方案强>
var counterRef = admin.firestore().collection('counters').doc('userId');
return admin.firestore().runTransaction(function(transaction) {
// This code may get re-run multiple times if there are conflicts.
return transaction.get(counterRef).then(function(counterDoc) {
var newValue = (counterDoc.data().value || 0) + 1;
transaction.update(counterRef, {
"value": newValue
});
});
}).then(t => {
admin.firestore().runTransaction(function(transaction) {
// This code may get re-run multiple times if there are conflicts.
return transaction.get(counterRef).then(function(counterDoc) {
var userIdCounter = counterDoc.data().value || 0;
var userObject = {
userId: userIdCounter
};
event.data.ref.set(userObject, {
merge: true
});
});
})
});