【发布时间】:2021-11-15 19:35:20
【问题描述】:
本地 SQL
在我的应用程序本地,我有数据模型 Foo 和 Bar,每个都存储在单独的 SQL 表中。
Foo 通过 id 引用 Bar,如果 Foo 没有对应的 Bar 是错误的。
有时它们会一起显示,有时一次只显示一个,并且可以编辑一个而不影响另一个。
Firebase 实时数据库
我现在正在研究如何最好地将它集成到我的应用程序中,以确保顺畅的同步和备份体验。一切都非常简单。 但我不知道如何确保上述合同保持真实。
会有 Foo 同步的情况;并且 Bar 仅在稍后的某个时间同步(考虑一个简单的网络连接断开)。在此期间,该特定用户的实时数据库将被视为处于非法状态。当连接恢复时, Foo 和 Bar 最终将同步并且整个事情可以继续流动 - 但在那之前我该怎么办?我该如何防范呢?我需要,还是在所有错误的地方寻找答案?
我一直在探索的一些想法:
- 允许在本地缺少 Bar。考虑 Foo 在其 bar 丢失时处于部分状态,例如在“准备就绪”之前,它可能会隐藏在 UI 中。
- 以某种方式在本地组合 Foo 和 Bar,仅在其 Bar 可用时才保存 Foo,等等。
- 在 Foo 内嵌套 Bar 以便它们始终同步在一起。 (这似乎很麻烦,我的应用程序中有几个关系,例如 Foo->Bar,如果这是处理它的“正确”方式,我必须将 Bar 嵌套在所有这些关系中)
如果可以,请赐教。 Firebase 对我来说并不陌生,但是将这种复杂的数据与多种关系同步却是。
附加上下文
虽然我无法分享实际的 Foo & Bar,但我有一个我认为与挑战非常相似的示例。
考虑一个包含消息、房间和用户的聊天应用程序。
您可以向房间发布消息,还可以编辑房间名称和颜色。没有用户和房间,消息就无法存在。从同步的角度来看,用户、房间和消息现在必须“一起”同步(或者至少,如果没有其他消息通过,消息将是无效的)。
使用多路径更新来处理这个问题,我会在每次发布/编辑消息时更新所有 3 个。我是否正确理解了这一点?如果是这样,那将意味着在我自己的场景中更新 1+N+N 个节点。 N+N 个节点不会有任何实际更新的数据,但会包含在更新中以确保所有数据同步在一起。
进一步明确
首先,回到问题的根源 - Foo 在本地通过其 id 引用 Bar。如果我的应用程序最终处于一个没有另一个存在的状态,它会在几乎所有地方引起问题(这就是我所说的非法状态,它不可能发生)。
考虑到防范它的方法,我被建议在 firebase 中使用多路径更新(我相信这与扇出相似/相同?)。我会尽快尝试这种方法,尽管我对此感到保留,只是为了验证我的感受是否只是缺乏经验。
我很难理解这样一个事实,即如果 Foo 在本地发生变化,它现在也会导致对 Bar 的查询,这样两者就可以一起同步到 firebase。对于这样一个简单的场景,这听起来不错,但在实践中,这意味着:您对 X 进行编辑并保存在本地,此后不久将同步到 firebase,现在 Y 和 Z 为 100:s也被查询,并在同一操作中插入到 firebase。此时 Y 和 Z 可能已经在 firebase 中保持最新状态,并且它们没有在本地更改。
当涉及到 firebase 时,我对这类场景没有太多经验,我的想法是这样的做法是对资源的巨大浪费 - 我确信 firebase 在本地做了很多工作,因此不会发生不必要的同步工作对于实际上没有改变的数据,但我无法摆脱这样的想法,即我仍然会在本地查询 100:s 和 100:s 的复杂模型很多,如果它没有似乎 是必要的(在我从另一个角度解决问题的情况下,肯定存在另一种方法吗?)。
【问题讨论】:
-
这个问题有点模糊,使用的一些语言不清楚。例如; Firebase 有事务,其中数据写入必须全部成功,否则全部失败。因此,当首次编写 Foo 和 Bar 时,将在事务中完成 - 这保证它们都存在,这将消除对象“丢失”的可能性(无论丢失意味着什么)。 “非法状态”是什么意思?如果 Firebase 中同时存在 Foo 和 Bar,并且 bar 在离线时被编辑,则当应用在线时,这些更改会同步并更新 Bar。或许你可以提供一个更具体的例子?
-
我在帖子中添加了一些“更清晰”的内容 - 希望现在更有意义。虽然事务有助于确保 Foo 和 Bar 同步成功或失败,但它仍然需要我执行所有这些查询(在我的帖子中有更多内容)。
-
不幸的是仍然很模糊。您说的是没有另一个存在并且具有事务性写入,这是不可能发生的。当 foo 和 bar 第一次被写入时,它将在保证它们都存在的写入事务中完成,因此一个没有另一个 - 是不可能的 -。此外,这个 *Foo 在本地通过其 id 引用 Bar。*` 在 Firebase 中不是一个概念;它是第一个在线数据库,并且在本地与在线引用某些内容“不是您可以做的”
-
另外,Firebase 不是关系数据库,因此 如果 Foo 在本地更改,现在也会导致发生 Bar 的查询 是不可能发生的事情。您可以查询 Foo 或更改 foo ,但这与 Bar 没有任何关系。例如您可以整天更新 Foo ,但这与查询 Bar 无关,因为它们不相关(因为如上所述,Firebase 不是关系数据库)。更具体的东西可能会帮助我们理解这个难题,但同样,Foo 和 Bar 是完全独立的数据片段,没有自动关系。
-
我所说的关系都是本地的(SQL);更新 Foo 导致查询 Bar 也是本地的,因为 Id 需要将 Bar 包含在我对 firebase 的更新中 Id 也需要在本地获取它。我确实缓存了,但是在我的场景中查询“Bar”实际上是来自不同表的 10 个查询,因此感觉非常无效。如果还有其他像扇出这样的“技术”,我很想知道;但我会给它一个诚实的机会。
标签: firebase firebase-realtime-database