Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Firebase实时数据库-间歇更新()与set()类似_Node.js_Firebase_Firebase Realtime Database_Google Cloud Functions_Firebase Admin - Fatal编程技术网

Node.js Firebase实时数据库-间歇更新()与set()类似

Node.js Firebase实时数据库-间歇更新()与set()类似,node.js,firebase,firebase-realtime-database,google-cloud-functions,firebase-admin,Node.js,Firebase,Firebase Realtime Database,Google Cloud Functions,Firebase Admin,Firebase实时数据库update()函数的工作方式似乎与set()函数的工作方式类似,这是间歇性的、不可预测的。有趣的是,它似乎发生在大约1%的更新操作上。但是我们已经执行了大量的日志记录,并且会看到一些事情发生,比如一个特定的更新被推送到一个循环中的一组用户,我们验证是否在日志中向所有用户发送了正确的信息,并且对每个记录调用了update()。然而,我们将看到的结果是,有时其中一个用户会得到一个只包含我们更新的字段的记录,而记录中的所有其他字段都会被删除,而所有其他用户都会正确地接收更新

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

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

const contactsRef = admin.database().ref().child('contacts');
...
//targetUID, contactID, contactObj get passed in via PubSub
...
contactsRef.child(targetUID).child(contactID).update(contactObj);
预期:
update()
只应更新传递给它的记录字段


实际:
update()
似乎像
set()
一样随机工作,大约有1%的时间。将从实时数据库中的目标记录中删除传递给
update()
的对象中未包含的任何字段。

对于1%的用户,数据库服务器的行为似乎不太可能不同。更有可能的是,这1%的用户拨打的电话略有不同。很难确定这与您共享的代码有什么区别,因此下面是一个有根据的猜测,希望能快速解除您的阻止

你说你会:

预期:
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
}
在这种情况下,仅更新
ref
下的
name
id
属性。其他属性未经修改,因此您最终会得到:

"uid1": {
  "name": "miles_b",
  "id": 2687721,
  "full_name": "unknown",
  "metadata": {
    "last_seen": "20 minutes ago",
    "reputation" 56
  }
}
但是现在,假设您还想更新
元数据/声誉
。你可能认为这是可行的:

ref.update{
  "name": "miles_b",
  "id": 2687721,
  "metadata": {
    "reputation": 61
  }
}
但是这里您告诉数据库用您提供的对象替换
元数据。因此,结果是:

"uid1": {
  "name": "miles_b",
  "id": 2687721,
  "full_name": "unknown",
  "metadata": {
    "reputation" 61
  }
}
这意味着上次看到的
现在已经从数据库中消失了

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

ref.update{
  "name": "miles_b",
  "id": 2687721,
  "metadata/reputation": 61
}
这样,您就可以在更新元数据/声誉时保留元数据/最后一次查看

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

正如我提到的,我们已经执行了大量的日志记录,以确保在调用update()函数时,正确的信息被传递到该函数中。对于任何特定的用户来说,这并不是始终如一的,而是在所有用户之间随机发生的。一两分钟后执行完全相同的更新可能会导致正确的预期行为。发生此错误时,将从数据库中的记录中删除更新调用中未明确包含的任何字段。与往常一样:如果显示问题的最小完整细节,将更容易提供帮助。我明白了,向我们展示如何重现这一点可能很难/不可能,但展示独立代码和日志表明它没有达到预期的效果应该是可能的。如果不是,我建议在故障排除方面提供个性化帮助,因为他们可能会查看您的项目中的奇怪之处。不过,他们通常也会先要求代码+日志记录,除非他们看到多个报告
"uid1": {
  "name": "miles_b",
  "id": 2687721,
  "full_name": "unknown",
  "metadata": {
    "last_seen": "20 minutes ago",
    "reputation" 61
  }
}