android51130
android51130

Reputation: 1115

Cloud Functions: Firestore triggers

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

Answers (2)

android51130
android51130

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

Mike McDonald
Mike McDonald

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

Related Questions