Firebase 实时数据库当前给出 TRIGGER_PAYLOAD_TOO_LARGE 错误

Posted

技术标签:

【中文标题】Firebase 实时数据库当前给出 TRIGGER_PAYLOAD_TOO_LARGE 错误【英文标题】:Firebase Realtime Database currently gives TRIGGER_PAYLOAD_TOO_LARGE error 【发布时间】:2018-11-03 22:03:35 【问题描述】:

从今天早上开始,我们的 Firebase 应用程序在向实时数据库实例写入数据时出现问题。即使是最简单的任务,例如向对象添加一个键值对也会触发

Error: TRIGGER_PAYLOAD_TOO_LARGE: This request would cause a function payload exceeding the maximum size allowed.

这特别奇怪,因为我们的代码或数据库中的任何内容都没有更改超过 24 小时。

即使是这么简单的事情

Database.ref('environments/' + envkey).child('orders/' + orderkey).ref.set(a:1)

触发错误。

显然,有效载荷的大小不是问题,但可能是什么原因造成的?

数据库结构,根据要求

environments +-env1 +-env2 --+orders ---+223344 -----customer: "Peters" -----country: "NL" -----+items ------item1 -------code: "a" -------value: "b" ------item2 -------code: "x" -------value: "2"

【问题讨论】:

您能否编辑您的问题以包括您的数据库结构的一般外观以及您的数据库触发器的外观? @DougStevenson 我添加了一个示例结构。这不是数据库触发器,某些 Angular 会触发一个函数,该函数使用 ref 到达正在更新数据的位置 此外,我们使用 firebase/5.0.3 和 angularfire v2.3.0 我们也刚刚开始收到此错误响应 好吧,这真的很古怪。运行日志以查看深度是否是问题所在,而我只有 10 级深度。我开始向上移动,我可以写得更高。然后我只是尝试在这个级别上写 ATALL ,现在它正在阻塞。我无法删除数据也无法写入数据。路径:/collections/data/id/items/abc/writeMe 尝试写入:true 并且 firebase 拒绝了写入 【参考方案1】:

好的,我想通了。该问题与您的写入功能无关,而是与写入操作将触发的云功能之一有关。

例如,我们有这样的结构: /collections/data/abcd/items/a 在 JSON 中:

"collections": 
    "data": 
        "abc": 
            "name": "example Col",
            "itemCount": 5,
            "items": 
                "a": "name": "a",
                "b": "name": "b",
                "c": "name": "c",
                "d": "name": "d",
                "e": "name": "e",
            
        
    

任何对项目的写入都失败了。 API、javascript,甚至是控制台中的基本编写。

我决定查看我们的云功能并发现:

  const countItems = (collectionId) => 
  return firebaseAdmin.database().ref(`/collections/data/$collectionId/items`).once('value')
    .then(snapshot => 
      const items = snapshot.val();
      const filtered = Object.keys(items).filter(key => 
        const item = items[key];
        return (item && !item.trash);
      );

      return firebaseAdmin.database().ref(`/collections/meta/$collectionId/itemsCount`)
        .set(filtered.length);
    );
;

export const onCollectionItemAdd = functions.database.ref('/collections/data/collectionId/items/itemId')
  .onCreate((change, context) => 
    const  collectionId  = context.params;
    return countItems(collectionId);
  );

它本身没什么,但触发读取所有项目,默认情况下,firebase 云函数将整个快照发送到 CF,即使我们不使用它也是如此。事实上,它也发送了之前和之后的值,所以如果你(像我们一样)有大量的项目,我猜它试图发送到云函数的有效负载太大了。

我从我们的 CF 和景气中删除了计数功能,恢复正常。如果我们根本没有触发器,则不确定进行计数的“正确”方法,但如果我们有,我会更新这个......

【讨论】:

非常感谢,确实是云函数在离数据库根太近的节点上触发的。 RE: 计数 - 我们使用带有“浅”的 REST 请求来实现这一点(即使来自云功能),那么您只需要监听 adds 和 删除【参考方案2】:

TRIGGER_PAYLOAD_TOO_LARGE 错误是 Firebase 正在推出的一项新功能的一部分,我们的 existing RTDB limits 正在严格执行。更改的原因是确保我们不会静默删除任何 Cloud Functions 触发器,因为任何超出这些限制的事件都无法发送到 Functions。

您可以通过调用 REST 自行关闭此功能:

curl -X PUT -d "false" https://<namespace>.firebaseio.com/.settings/strictTriggerValidation/.json?auth\=<SECRET>

<SECRET> 是你的DB secret

请注意,如果您禁用此功能,当前失败的请求可能会通过,但您对超出我们限制的请求触发的任何 Cloud Functions 都将无法运行。如果您正在为您的函数使用数据库触发器,我建议您重新构造您的请求,使它们保持在限制范围内。

【讨论】:

出现此错误。如果我们超出了任何限制,是否有可能知道/what/ 超出了限制?我们看不到我们进行了任何会导致问题的分组操作或类似操作。 Firebase 在不提供任何更多信息的情况下强制执行此操作,而且 Firebase 文档没有提及 TRIGGER_PAYLOAD_TOO_LARGE 错误,这有点荒谬。 之后有什么办法可以重新开启吗? 是的,只需将“false”切换为“true” 数据库机密现已弃用。有什么不同吗?

以上是关于Firebase 实时数据库当前给出 TRIGGER_PAYLOAD_TOO_LARGE 错误的主要内容,如果未能解决你的问题,请参考以下文章

OrderByKey 工作正常,但 OrderByChild 在 firebase 实时数据库中给出了意想不到的结果

如何获取当前的 Firebase UID 并将其写入实时数据库?

向 Firebase 实时数据库添加新值时如何保存当前日期/时间

在android studio中使用firebase实时数据库检索当前登录用户的数据

使用 Firebase 实时数据库 Flutter 进行实时更新

如何使用颤振从firebase实时检索数据