0

I'm using the below code to delete all old data every night.

Each function works fine on it's own and if I create multiple schedule tasks, one for each function, it also works fine. However, when I combine them into a single Scheduled Task called scheduledCleanData, I'm receiving Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information. at GoogleAuth.getApplicationDefaultAsync (/workspace/node_modules/google-auth-library/build/src/auth/googleauth.js:161:19) at process._tickCallback (internal/process/next_tick.js:68:7)

As per this post, I believe this is caused by the functions not waiting for the callbacks, rather than problems with the credentials. However adding async or await keywords cause a parse error. Some of these collections need to delete thousands of records.

Any help how to modify this code to correctly wait would be greatly appreciated!

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const client = require('firebase-tools');
admin.initializeApp(functions.config().firebase)
const db = admin.firestore();

const runtimeOpts = {
    timeoutSeconds: 300,
    memory: '1GB'
}

exports.scheduledCleanData = functions
    .runWith(runtimeOpts)
    .pubsub.schedule('0 3 * * *')
    .timeZone('America/Chicago')
    .onRun((context) => {
        return cleanOldAssignments()
            .then(cleanOldDuties())
            .then(cleanOldEvents())
            .then(console.info("scheduledCleanData Complete!"));
    });

function cleanOldAssignments() {
    const dateYesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));   // 24 hours
    return db.collectionGroup('assignments').where('date', '<', dateYesterday).get()
        .then(querySnapshot => {
            console.info("Old assignments to remove: " + querySnapshot.size);
            const promises = [];
            querySnapshot.forEach(doc => {
                promises.push(doc.ref.delete());
            });
            return Promise.all(promises);
        });
}

function cleanOldDuties() {
    const dateYesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));   // 24 hours
    return db.collectionGroup('duties').where('date', '<', dateYesterday).get()
        .then(querySnapshot => {
            console.info("Old duties to remove: " + querySnapshot.size);
            const promises = [];
            querySnapshot.forEach(doc => {
                promises.push(doc.ref.delete());
            });
            return Promise.all(promises);
        });
}

function cleanOldEvents() {
    const dateYesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));   // 24 hours
    return db.collectionGroup('events').where('date', '<', dateYesterday).get()
        .then(querySnapshot => {
            console.info("Old events to remove: " + querySnapshot.size);
            const promises = [];
            querySnapshot.forEach(doc => {
                promises.push(doc.ref.delete());
            });
            return Promise.all(promises);
        });
}
Damian
  • 119
  • 1
  • 10

1 Answers1

0

If cleanOldDuties and cleanOldEvents both return more promises, your code is not taking them into account. You will need to explicitly return their values to propagate down the promise chain:

    return cleanOldAssignments()
        .then(() => { return cleanOldDuties() })
        .then(() => { return cleanOldEvents() })

Without seeing the exact code of these other functions, it's not certain if this will work or not. Those functions have to be implemented correctly as well.

async/await is almost always a clearer way to express these sorts of things. You are probably just using them incorrectly as well.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Hi Doug, thanks for your message. The code for cleanOldDuties and cleanOldEvents is also shown above. All code is there. I've adjust the code and still get the Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information. at GoogleAuth.getApplicationDefaultAsync (/workspace/node_modules/google-auth-library/build/src/auth/googleauth.js:161:19) at process._tickCallback (internal/process/next_tick.js:68:7) – Damian Jul 21 '20 at 04:41