【问题标题】:Universal Firestore trigger for all documents所有文档的通用 Firestore 触发器
【发布时间】:2019-08-20 09:04:44
【问题描述】:

如何触发 Firestore 中任何集合中的任何文档更改的函数?我想管理createdAtupdatedAt 时间戳。我有很多集合,不想为每个集合单独注册触发器。那时我不妨为addsetupdate 创建包装函数。

如何注册一个在任何文档被修改时触发的回调?

编辑:

此时(2019-08-22),我决定只创建一个包装函数来实现此功能。接受的答案不保持模式少。基于this article,我创建了这个upset 函数来管理时间戳并避免“文档不存在”错误:

const { firestore: { FieldValue } } = require('firebase-admin')

module.exports = async function upset (doc, data = {}) {
  const time = FieldValue.serverTimestamp()

  const update = { updatedAt: time }
  const updated = { ...data, ...update }

  try {
    const snapshot = await doc.get()

    if (snapshot.exists) {
      return doc.update(updated)
    } else {
      const create = { createdAt: time }
      const created = { ...updated, ...create }

      return doc.set(created)
    }
  } catch (error) {
    throw error
  }
}

【问题讨论】:

  • 我除了下面的答案,你可以看看这个答案stackoverflow.com/questions/52660962/…(特别是“HOWEVER”部分)。
  • 参考文章现已付费。您如何将upset 绑定到所有 Firestore 中的每个集合/子集合?为什么叫upset 而不是upsert (update + insert)?
  • 据我所知,它无法绑定。每当我触摸文档时,我都会在我的云函数中手动调用不高兴。名称 upset 是两个 firebase 函数名称的组合,updatesetupdate + set = upset.

标签: firebase triggers google-cloud-firestore google-cloud-functions


【解决方案1】:

正如doc 中所述,您可以在文档路径中使用通配符。更具体地说,“您可以定义任意数量的通配符来替换显式集合或文档 ID”

因此,以下 Cloud Function 将适用于根集合下的文档:

exports.universalFirestoreTrigger = functions.firestore
    .document('{collecId}/{docId}')
    .onWrite((snap, context) => {

        console.log("Collection: " + context.params.collecId);
        console.log("Document: " + context.params.docId);

        return null;

    });

如果有子集合,则需要再写一个Cloud Function,如下:

exports.universalFirestoreTriggerSubCollections = functions.firestore
    .document('{collecId}/{docId}/{subCollecId}/{subDocId}')
    .onWrite((snap, context) => {

        console.log("Collection: " + context.params.collecId);
        console.log("Document: " + context.params.docId);
        console.log("Sub-Collection: " + context.params.subCollecId);
        console.log("Sub-Collection Document: " + context.params.subDocId);

        return null;

    });

如果你有子子集合,依此类推......

【讨论】:

  • 感谢您的回答和评论。目前,最好只创建一个包装函数以保持无模式。如果没有无模式方式,我发现这篇文章提供了一些示例(在 TypeScript 中):angularfirebase.com/lessons/…
  • 显然,使用FieldValue.serverTimestamp() 是自动维护createdAtupdatedAt 时间戳的最佳方式,如您参考的页面中所述(angularfirebase.com/lessons/…
  • 我在问题中添加了一个示例实现。
猜你喜欢
  • 2019-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 1970-01-01
  • 2019-02-13
相关资源
最近更新 更多