3
votes

Cloud Firestore - Cloud Functions:TypeError: collectionRef.child is not a function

I'm using Cloud Functions to update the comments number in the parent collection of Cloud Firestore, so when a comment added the Cloud Functions can automatically update the comment number.

Cloud Firestore - Cloud Functions:TypeError: collectionRef.child is not a function at exports.updateCommentNumbers1.functions.firestore.document.onCreate (/user_code/index.js:23:33) at Object. (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:112:27) at next (native) at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71 at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12) at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:82:36) at /var/tmp/worker/worker.js:716:24 at process._tickDomainCallback (internal/process/next_tick.js:135:7)

the code is:

exports.updateCommentNumbers1 = functions.firestore
.document('postlist/{postlistId}/comments/{commentsID}')
.onCreate((change, context) => 
{
    const collectionRef = change.ref.parent;
    const countRef = collectionRef.child('comment_number');

    let increment;
    if (change.after.exists() )
    {
        increment = 1;
    }
     else 
    {
        return null;
    }

    return countRef.transaction((current) => 
    {
        return (current || 0) + increment;
    }).then(() => 
    {
        return console.log('Comments numbers updated.');
    });
});

The question is

  1. How can I refer a parent collection through its subcollection?

  2. How can I get the parent collection's field value and update it?

Thank you.

2

2 Answers

3
votes

collectionRef in your code is a CollectionReference type object. As you can see from the API docs, there is no child() method on that object. In fact, collections don't have any assignable properties at all. You can only store information in documents, and documents must exist within some collection.

So, you're going to have to figure out which document (in which collection) you want to store this count value, and modify some field in that document instead.

Also, the first argument passed to the anonymous function you pass to onCreate is not a "change" object. It's a DocumentSnapshot. onUpdate and onWrite receive "change" objects, which is a different thing.

2
votes

Finally, It took me more than two days to figure it out:

The first question's answer is change.after.ref.parent;

The example of the cloud functions for Cloud Firestore is very little.

All examples are firebase realtime database.

exports.updateCommentNum = functions.firestore
.document('post/{postId}/comments/{commentsID}')
.onWrite((change, context) => 
{

    const db = admin.firestore();
    const collectionRef = change.after.ref.parent;//'post/{postId}/comments/'
    const countRef = collectionRef.parent;//'post/{postId}/'

    return db.runTransaction(t => 
    {
        return t.get(countRef).then(restDoc => 
        {
            var newNumber;
            newNumber = restDoc.data().comment_number + 1;
            newNumber = newNumber || 1;//filter any "falsey" value to 1.
            //The "falsey" values are:false/null/undefined/0/"" ( empty string )/NaN ( Not a Number )

            return t.set(countRef, {comment_number: newNumber}, {merge: true});
        });
    });


});