首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Firebase实时数据库-间歇性更新()的工作方式类似于set()

Firebase实时数据库-间歇性更新()的工作方式类似于set()
EN

Stack Overflow用户
提问于 2018-12-21 07:20:59
回答 1查看 154关注 0票数 0

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

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

代码语言:javascript
复制
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()的对象中未包含的任何字段都将从实时数据库的目标记录中删除。

EN

回答 1

Stack Overflow用户

发布于 2018-12-21 07:46:46

对于1%的用户,数据库服务器的行为似乎不太可能有所不同。更有可能的是,1%的用户发出的呼叫中存在细微的差异。很难确定这与你分享的代码有什么不同,所以下面是一个有根据的猜测,希望能迅速解除你的封锁。

你说你愿意:

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

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

这有点微妙,不幸的是,您没有展示如何构造contactObj。因此,我将举一个例子。假设您从JSON开始:

代码语言:javascript
复制
"uid1": {
  "name": "unknown",
  "id": -1,
  "full_name": "unknown",
  "metadata": {
    "last_seen": "20 minutes ago",
    "reputation" 56
  }
}

然后在该位置运行此命令:

代码语言:javascript
复制
ref.update{
  "name": "miles_b",
  "id": 2687721
}

在这种情况下,只更新ref下的nameid属性。其他属性都是未修改的,因此您最终得到:

代码语言:javascript
复制
"uid1": {
  "name": "miles_b",
  "id": 2687721,
  "full_name": "unknown",
  "metadata": {
    "last_seen": "20 minutes ago",
    "reputation" 56
  }
}

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

代码语言:javascript
复制
ref.update{
  "name": "miles_b",
  "id": 2687721,
  "metadata": {
    "reputation": 61
  }
}

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

代码语言:javascript
复制
"uid1": {
  "name": "miles_b",
  "id": 2687721,
  "full_name": "unknown",
  "metadata": {
    "reputation" 61
  }
}

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

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

代码语言:javascript
复制
ref.update{
  "name": "miles_b",
  "id": 2687721,
  "metadata/reputation": 61
}

这样,您就可以在更新metadata/reputation的同时保留metadata/last_seen

代码语言:javascript
复制
"uid1": {
  "name": "miles_b",
  "id": 2687721,
  "full_name": "unknown",
  "metadata": {
    "last_seen": "20 minutes ago",
    "reputation" 61
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53877346

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档