【问题标题】:delete data in firestore after n time using cloud functions使用云功能在 n 次后删除 firestore 中的数据
【发布时间】:2021-02-04 15:53:02
【问题描述】:

我一直在尝试找到一种方法,在我的案例 24 小时后,可以在一定时间后删除 firestore 中的集合中的文档,为此我意识到我必须使用 firebase 云功能,所以在调查后我找到了这个post,它完成了我需要在我的项目中添加的工作,除了我使用的是打字稿而不是那个问题中使用的javascript,我无法将其更改为javascript,因为我已经在使用typecipt发送通知给用户。如何将以下代码更改为 typescript?

//index.ts
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp()

const db = admin.firestore();
export const deleteOldItems = functions.database
    .ref('stories/{storyId}')
    .onWrite((change, context) => {
        var ref = change.after.ref.parent; 
        var now = Date.now();
        var cutoff = now - 24 * 60 * 60 * 1000;
        var oldItemsQuery = ref.orderByChild('created').endAt(cutoff);
        return oldItemsQuery.once('value', function(snapshot) {
            // create a map with all children that need to be removed
            var updates = {};
            snapshot.forEach(function(child) {
              updates[child.key] = null
            });
            // execute all updates in one go and return the result to end the function
            return ref.update(updates);
          });
    });

这是需要在 24 小时后删除的数据的图像,created 字段是创建文档的日期,deleted id 是应该删除文档的日期。

编辑: 我发现问题不是因为使用了打字稿,而是因为我使用的是 firestore 而不是 firebase 实时数据库,所以我创建了这段代码,它应该可以让事情正常工作,但它没有.我该如何解决这个问题?

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp()


const db = admin.firestore();
export const deleteOldItems = functions.firestore
    .document('stories/{storyId}')
    .onWrite(async (change, context) => {
        const getData = await db.collection('stories').where('deleted', '>', Date.now()).get().then(
            (snapshot) => snapshot.forEach((doc) =>
                doc.ref.delete()
            )
        );
        return getData;
    });

【问题讨论】:

  • 任何有效的 JavaScript 都是自动有效的 TypeScript,在那里不需要转换。但是您共享的代码是用于 Firebase 实时数据库(我应该知道,正如我所写的那样),而您正在使用 Cloud Firestore。您需要调整它以适应该数据库的 API。
  • @FrankvanPuffelen 谢谢你,我没有注意到,我会尝试调整它,如果它有效,我会发布答案。

标签: node.js typescript firebase google-cloud-firestore google-cloud-functions


【解决方案1】:

您将async/awaitthen 混合在一起,此外,您无需等待对delete() 异步方法的调用集全部完成。所以云函数平台可能会在所有工作完成之前清理云函数实例。在返回 Promise 或值之前,您需要等待所有这些异步工作完成。更多详情 here 在文档中。

以下应该可以解决问题:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp()


const db = admin.firestore();
export const deleteOldItems = functions.firestore
    .document('stories/{storyId}')
    .onWrite(async (change, context) => {
        const querySnapshot = await db.collection('stories').where('deleted', '>', Date.now()).get();

        const promises = [];
        querySnapshot.forEach((doc) => {
            promises.push(doc.ref.delete());
        });
        return Promise.all(promises);
    });

由于要删除不定数量的文档,需要使用Promise.all()并行执行异步删除任务(因为delete()方法返回一个Promise)。

更新以下 cmets 中的问题:

1/ Promise.all() 返回一个 single Promise,它解析为输入 Promise 的结果数组。 当数组中的所有 Promise 都已解决时,此返回的 Promise 将解决。 Promise.all() 的主要兴趣在于它返回单个 Promise,因此您可以轻松知道何时所有对异步 delete() 方法(返回 Promise)的调用完成。

2/ onWrite 事件类型在创建、修改或删除文档时触发。由于您在问题中使用了此事件类型,因此我保留了它。如果要安排执行,请使用scheduled Cloud Function。 “内码”一模一样。

【讨论】:

  • 基本上还有这个promises数组,它存储了所有应该被删除的文档,当调用return Promises.all(promises)时,数组中的文档被删除了对吧?
  • 嘿 Renaud 一个问题,您的代码应该在文档超过 24 小时时自动运行,还是必须调用它?
  • 成功了!感谢您的帮助,我非常感谢;)
【解决方案2】:

我认为“.onWrite(async (change, context)”它只在创建文档时调用,你需要每x次创建一个任务来检查是否有要删除的文档,然后你进行查询并删除文件。

你可以从你的服务器或任务调度器中使用 Cron 作业,我认为谷歌云有自己的任务调度器。

一个函数的持续时间不能超过 60 秒,之后会发送错误。

【讨论】:

  • 嘿!我怎样才能每 x 次创建一个任务?可以提供代码吗?
  • 你在什么样的服务器上构建你的代码?
猜你喜欢
  • 2018-04-23
  • 2021-08-09
  • 2021-02-13
  • 2020-08-02
  • 2018-06-30
  • 2019-11-12
  • 1970-01-01
  • 2023-02-09
  • 2021-08-19
相关资源
最近更新 更多