Reputation: 1115
I want to write cloud function for Firestore which will decrement task.elapsedCount and make user.points += 3 in two parallel threads:
exports.taskDoneFunc = functions.firestore
.document('/tasks/{taskId}')
.onUpdate(event => {
const taskRef = event.data.ref;
const root = taskRef.root;
return taskRef.get()
.then(taskSnap => {
let task = taskSnap.data();
task.elapsedCount -= 1;
taskRef.set(task, {merge: true})
return root.document('/users/${task.taskOwner_uid}').get()
}).then(userSnap => {
let user = userSnap.data();
user.points += 3;
return userSnap.ref.set(user)
})
});
first Promise works fine and I see changes in task Firestore "task" document, but second says "Cannot read property 'document' of undefined".
I've not found any clean examples for Cloud Functions for Firestore database triggers, this is crazy Beta? :(
Upvotes: 0
Views: 732
Reputation: 1115
I've just figured out howTo work with functions in Firestore: just
admin.firestore().doc(/users/${uid}).get()
-like calls. If it will be helpful for someone :)
Upvotes: 0
Reputation: 15963
I don't believe root
is defined in a Firestore DocumentReference
(docs). Instead, I believe you want to use firestore
(docs), which gets the top level Firestore database:
exports.taskDoneFunc = functions.firestore
.document('/tasks/{taskId}')
.onUpdate(event => {
const taskRef = event.data.ref;
const db = taskRef.firestore;
const task;
return taskRef.get()
.then(taskSnap => {
task = taskSnap.data();
task.elapsedCount -= 1;
return taskRef.set(task, {merge: true})
}).then(() => {
return db.collection('users').doc(task.taskOwner_uid).get();
}).then(userSnap => {
let user = userSnap.data();
user.points += 3;
return userSnap.ref.set(user)
})
});
I think there was also a potential race condition with two async functions (the set followed by the get).
Upvotes: 1