Rhywden
Rhywden

Reputation: 750

Firebase Functions not firing for Cloud Firestore

I simply cannot see where I'm going wrong here. My Cloud Firestore is on "europe-west3", the functions are deployed to "europe-west1" (the docs tell me that this is the closest location to west3).

Structure is thus: I've got a bunch of "tickets" each of which can have a subcollection named "comments". The console thus looks like this:

Console

The upload was successful:

Functions console

The function code was taken from the official code samples Github repo for Function samples

This is what my code looks like:

const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp();

exports.countComments = functions.region('europe-west1').database.ref('/tickets/{ticketId}/comments/{commentsid}')
    .onWrite(
        async (change) => {
            const ticketsRef = change.after.ref.parent;
            const countRef = ticketsRef.parent.child('comments_count');

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

            await countRef.transaction((current) => {
                return (current || 0) + increment;
            });
            console.log('Counter updated');
            return null;
        });

exports.recountComments = functions.region('europe-west1').database.ref('/tickets/{ticketId}/comments_count')
    .onDelete(
        async (snap) => {
            const counterRef = snap.ref;
            const collectionRef = counterRef.parent.child('comments');
            const commentsData = await collectionRef.once('value');
            return await counterRef.set(commentsData.numChildren());
        }
    )

Now, the problem is that these functions simply do not fire. I'm not seeing anything in the logs, regardless of whether I'm pushing changes through my clients (a Flutter app) or if I'm changing things directly in the Firebase console.

In my desperation I've also tried to simply listen to "/tickets" as any changes below that path should also trigger - but there's nothing.

So. What is the obvious thing I overlooked? And, yes, I had a look at the other questions/answers but nothing jumped at me...

edit:

This would be the corrected version, probably not optimal.

exports.countComments = functions.region('europe-west1').firestore.document('/tickets/{ticketId}/comments/{commentsId}')
    .onWrite(
        async (change, context) => {
            const ticketId = context.params.ticketId;
            const ticketRef = admin.firestore().collection('tickets').doc(ticketId);

            let increment;
            if(change.after.exists && !change.before.exists) {
                increment = 1;
            } else if(!change.after.exists && change.before.exists) {
                increment = -1;
            } else {
                return null;
            }
            return transaction = admin.firestore().runTransaction(t => {
                return t.get(ticketRef)
                    .then(doc => {
                        let count = (doc.data().comments_count || 0) + increment;
                        t.update(ticketRef, {comments_count: count});
                    });
            }).then(res => {
                console.log('Counter updated');
            }).catch(err => {
                console.log('Transaction error:', err);
            });
        });

Upvotes: 0

Views: 386

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317828

Your database is Cloud Firestore, but you've written a Realtime Database trigger. They are two completely different databases. Follow the documentation for writing Cloud Firestore triggers instead.

Your function will start like this:

functions.region('europe-west1').firestore.document('...')

Note "firestore" instead of "database".

Upvotes: 2

Related Questions