简体   繁体   中英

How to efficiently delete old Firebase Cloud documents using a Google Cloud Function?

I am currently using the following scheduled Cloud Function to delete any Assignments or Duties (documents) older than 24 hours. The function works fine, and the documents successfully delete.

However a HUGE amount of Reads are being reported by the function. It seems that every single assignment or duty is being "read", regardless of whether it needs to be deleted or not. It was my understanding that queries do count as reading, unless they return a document in the querySnapshot that is used? EG Any documents do be deleted will have a READ and DELETE.

Does anyone know how to optimize this to only read documents that must be deleted? Or is there an easier way to delete old Cloud Firebase documents using a Google Cloud Function? I would have thought this is a really common thing to do.

* UPDATED #2 with collectionGroup and correct use of Promises (Thanks for your help!) *

Same problem: When the function is run, it is showing 844 Reads and 1 Delete. There is definitely no other sources reading the data. The spikes only occur right after running the function (using Google Cloud Scheduler - Run Now)

Interestingly, if there are NO documents to delete, then there are NO reads recorded. But if there is > 1 document to delete, there are hundreds of Reads. Currently there are only about 120 Duties in the whole collection! It seems each duty is being read multiple times!?

在函数运行后立即读取 Spike

在此处输入图片说明

Thanks!

exports.scheduledCleanOldDutiesCollection = functions.pubsub.schedule('0 3 * * *')
    .timeZone('America/Chicago')
    .onRun((context) => {
        const dateYesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));   // 24 hours
        return db.collectionGroup('duties').where('date', '<', dateYesterday).get()
            .then(querySnapshot => {
                const promises = [];
                querySnapshot.forEach(doc => {
                    promises.push(doc.ref.delete());
                });
                return Promise.all(promises);
            });
    });

As Doug explained in his comment and in the official video series , your code must return a promise that resolves only after all the asynchronous work is complete, else the Cloud Function will get terminated early.

You can adapt your code as follows, by using Promise.all() :

exports.scheduledCleanOldDutiesCollection = functions.pubsub.schedule('0 3 * * *')
    .timeZone('America/Chicago')
    .onRun((context) => {
        const dateYesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));   // 24 hours
        return db.collectionGroup('duties').where('date', '<', dateYesterday).get()
            .then(querySnapshot => {
                const promises = [];
                querySnapshot.forEach(doc => {
                    promises.push(doc.ref.delete());
                });
                return Promise.all(promises);
            });
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM