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()
的对象中未包含的所有字段。
答案 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
下的id
和ref
属性被更新。其他属性未修改,因此最终得到:
"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
}
}