如何为每个集合插入添加时间戳,如何在Cloud Functions中更新Firestore数据库

Mus*_*afa 3 firebase firebase-realtime-database google-cloud-functions angularfire2 google-cloud-firestore

我有一个名为Posts的Firestore集合,我在客户端插入了一个插件,即可正常工作。

我想使用firebase函数将createdAt和updatedAt字段添加到我的帖子集合firestore中的每个插入中。

Jon*_*han 18

21 年 1 月 31 日更新- 虽然我相信我的包是很棒的代码并回答了这个问题,但有一种更便宜的方法:firestore 规则

allow create: if request.time == request.resource.data.createdAt;
allow update: if request.time == request.resource.data.updatedAt;
Run Code Online (Sandbox Code Playgroud)

如果updatedAtcreatedAt与正确的日期和时间的前端不会添加,也不会允许更新/创建。这要便宜得多,因为它不需要数据函数,也不需要每次更新内容时进行额外写入。

不要使用常规日期字段,请务必通过以下方式在前端添加时间戳:

firebase.firestore.FieldValue.serverTimestamp;
Run Code Online (Sandbox Code Playgroud)

20 年 11 月 24 日更新- 我实际上将以下函数放在我的 npm 包adv-firestore-functions 中

见我的博客文章:https : //fireblog.io/blog/post/automatic-firestore-timestamps


我创建了一个通用的云函数来使用 createdAt 和 updatedAt 时间戳更新您想要的任何文档:

exports.myFunction = functions.firestore
    .document('{colId}/{docId}')
    .onWrite(async (change, context) => {

        // the collections you want to trigger
        const setCols = ['posts', 'reviews','comments'];

        // if not one of the set columns
        if (setCols.indexOf(context.params.colId) === -1) {
            return null;
        }

        // simplify event types
        const createDoc = change.after.exists && !change.before.exists;
        const updateDoc = change.before.exists && change.after.exists;
        const deleteDoc = change.before.exists && !change.after.exists;

        if (deleteDoc) {
            return null;
        }
        // simplify input data
        const after: any = change.after.exists ? change.after.data() : null;
        const before: any = change.before.exists ? change.before.data() : null;

        // prevent update loops from triggers
        const canUpdate = () => {
            // if update trigger
            if (before.updatedAt && after.updatedAt) {
                if (after.updatedAt._seconds !== before.updatedAt._seconds) {
                    return false;
                }
            }
            // if create trigger
            if (!before.createdAt && after.createdAt) {
                return false;
            }
            return true;
        }

        // add createdAt
        if (createDoc) {
            return change.after.ref.set({
                createdAt: admin.firestore.FieldValue.serverTimestamp()
            }, { merge: true })
                .catch((e: any) => {
                    console.log(e);
                    return false;
                });
        }
        // add updatedAt
        if (updateDoc && canUpdate()) {
            return change.after.ref.set({
                updatedAt: admin.firestore.FieldValue.serverTimestamp()
            }, { merge: true })
                .catch((e: any) => {
                    console.log(e);
                    return false;
                });
        }
        return null;
    });


Run Code Online (Sandbox Code Playgroud)

  • 这是很棒的东西——你真的应该把它写在一篇 Medium 文章或其他东西中。我认为它唯一缺少的是包含子集合的能力。我会考虑一下这会如何发生 (4认同)

Ren*_*nec 6

为了通过Cloud Function createdAtPost记录添加时间戳,请执行以下操作:

exports.postsCreatedDate = functions.firestore
  .document('Posts/{postId}')
  .onCreate((snap, context) => {
    return snap.ref.set(
      {
        createdAt: admin.firestore.FieldValue.serverTimestamp()
      },
      { merge: true }
    );
  });
Run Code Online (Sandbox Code Playgroud)

为了将modifiedAt时间戳添加到现有时间戳,Post您可以使用以下代码。无论其,这个云功能将每个文件后的现场变化,包括更改时间触发createdAt,并为updatedAt领域,以无限循环结束 ....

exports.postsUpdatedDate = functions.firestore
  .document('Posts/{postId}')
  .onUpdate((change, context) => {
    return change.after.ref.set(
      {
        updatedAt: admin.firestore.FieldValue.serverTimestamp()
      },
      { merge: true }
    );
  });
Run Code Online (Sandbox Code Playgroud)

因此,您需要比较文档的两种状态(即,change.before.data()change.after.data()检查更改是否涉及的字段不是createdAtor updatedAt

例如,假设您的Post文档仅包含一个字段name(不考虑两个时间戳字段),则可以执行以下操作:

exports.postsUpdatedDate = functions.firestore
  .document('Posts/{postId}')
  .onUpdate((change, context) => {
    const newValue = change.after.data();
    const previousValue = change.before.data();

    if (newValue.name !== previousValue.name) {
      return change.after.ref.set(
        {
          updatedAt: admin.firestore.FieldValue.serverTimestamp()
        },
        { merge: true }
      );
    } else {
      return false;
    }
  });
Run Code Online (Sandbox Code Playgroud)

换句话说,恐怕您必须逐字段比较两个文档状态。