Firebase实时数据库-间歇性地update()的作用类似于set()

时间:2018-12-20 23:20:59

标签: node.js firebase firebase-realtime-database google-cloud-functions firebase-admin

Firebase实时数据库/usr/bin/bison函数间歇性且不可预测地像update()函数那样工作。有趣的是,它似乎发生在大约1%的更新操作上。但是我们已经进行了广泛的日志记录,并且会看到类似循环中向一组用户推出特定更新的情况,我们会验证是否在日志中向所有用户发送了正确的信息,并且{ 1}}在每个记录上被调用。但是,我们将看到的结果是,有时其中一个用户会收到一条仅包含我们更新的字段的记录,而记录中的所有其他字段都会被删除,而所有其他用户都将正确接收更新。随后运行完全相同的set()操作将导致所有内容均按预期进行更新。这是一个已知的问题?有什么解决方法吗?我们正在节点8.14.0上运行firebase-admin 6.0.0

尝试对update()函数进行多次重复测试。没有确定的方法可以使此问题重现,但它在生产中是随机发生的。

update()

预期:update()仅应更新传递给它的记录字段。

实际:const contactsRef = admin.database().ref().child('contacts'); ... //targetUID, contactID, contactObj get passed in via PubSub ... contactsRef.child(targetUID).child(contactID).update(contactObj); 似乎像update()那样随机工作,大约有1%的时间。从实时数据库中的目标记录中删除要传递给update()的对象中未包含的所有字段。

1 个答案:

答案 0 :(得分:1)

对于1%的用户,数据库服务器的行为似乎不太可能出现差异。 1%的用户拨打电话的可能性很小。很难确定与您共享的代码有什么区别,所以下面是一个有根据的猜测,希望能迅速解除对您的阻止。

你说你这样做:

contactsRef.child(targetUID).child(contactID).update(contactObj);
     

预期:update()仅应更新传递给它的记录字段。

有点微妙,不幸的是您没有展示如何构造contactObj。所以我举一个例子。假设您以JSON开头:

"uid1": {
  "name": "unknown",
  "id": -1,
  "full_name": "unknown",
  "metadata": {
    "last_seen": "20 minutes ago",
    "reputation" 56
  }
}

然后您在该位置上运行此

ref.update{
  "name": "miles_b",
  "id": 2687721
}

在这种情况下,仅name下的idref属性被更新。其他属性未修改,因此最终得到:

"uid1": {
  "name": "miles_b",
  "id": 2687721,
  "full_name": "unknown",
  "metadata": {
    "last_seen": "20 minutes ago",
    "reputation" 56
  }
}

但是现在说您还想更新metadata/reputation。您可能会认为这可行:

ref.update{
  "name": "miles_b",
  "id": 2687721,
  "metadata": {
    "reputation": 61
  }
}

但是在这里,您告诉数据库将metadata替换为您提供的对象。结果是:

"uid1": {
  "name": "miles_b",
  "id": 2687721,
  "full_name": "unknown",
  "metadata": {
    "reputation" 61
  }
}

这意味着last_seen现在已经从数据库中消失了。

要更新嵌套属性,请在键中包含其完整路径。所以:

ref.update{
  "name": "miles_b",
  "id": 2687721,
  "metadata/reputation": 61
}

因此,您将保留metadata/last_seen,同时更新metadata/reputation

"uid1": {
  "name": "miles_b",
  "id": 2687721,
  "full_name": "unknown",
  "metadata": {
    "last_seen": "20 minutes ago",
    "reputation" 61
  }
}