【问题标题】:Some questions about keepSynced(true) on a limited query reference关于有限查询参考的 keepSynced(true) 的一些问题
【发布时间】:2020-07-16 19:59:11
【问题描述】:

我有一个由 Firebase 支持的应用,其数据库结构如下:

posts
      /uid
           /postId

最初,我会使用ObserveEventOfType.childAddedposts/uid 节点加载数据。这会同时为我的应用程序的所有用户频繁加载陈旧数据(每天约 5 次)。当尝试通过发布新帖子来更新数据时,Firebase 仍会返回过时的数据。

因此,我决定尝试keepSynced。现在,如果我的参考看起来像这样:

reference = Database().database.reference.child("posts").child(uid)

keepSynced 将加载该节点上的所有数据,如果该节点中有很多子节点,这可能会导致下载量非常大。因此,我决定将引用/查询更改为:

reference = Database().database.reference.child("posts").child(uid).queryLimited(toLast: 25)

当为此节点打开keepSynced 时,它会成功同步节点中的最后 25 个子节点。但是,我仍然面临相当频繁地接收陈旧数据的问题。所以这是我的问题:

  1. 在受限查询中添加keepSynced 模式时,它是仅从您添加到的初始节点同步,还是始终只同步该节点下的 25 个最新子节点?

  2. 在代码中添加keepSynced(true) 行的最佳位置在哪里?在我们加载引用之前,在viewWillAppear 中,还是在实际下载回调中?

  3. 同样,在哪里使用keepSynced(false) 最好?

  4. 当应用淡入后台时,keepSynced 监听器是否会被删除?

  5. 为什么keepSynced 有时不处理子更新?

我目前在用于加载在viewDidLoad 上调用的帖子的函数内部使用keepSynced(true)

提前致谢。

【问题讨论】:

    标签: ios swift firebase caching firebase-realtime-database


    【解决方案1】:

    顾名思义,keepSynced(true) 将您调用的任何查询或引用保持在本地缓存中同步。它实际上只是将一个空观察者附加到该查询/引用。因此,在您的 Database().database.reference.child("posts").child(uid).queryLimited(toLast: 25) 中,它将同步最后 25 个子节点,并继续同步那些(在添加新节点时删除以前的节点)。

    如果您重复侦听完全相同的数据,Firebase 实时数据库缓存机制的工作最可靠。具体来说,附加到Database().database.reference.child("posts").child(uid).value 侦听器可能看不到通过Database().database.reference.child("posts").child(uid).queryLimited(toLast: 25) 缓存的数据。这是因为 Firebase 客户端保证永远不会为部分更新触发事件,在此示例中,它不能保证它具有来自第一个引用的所有数据。

    对于您的问题:

    1. 见上文...

    2. 最常见的是将它们添加到viewWillAppear

    3. 我不知道你为什么要打电话给keepSynced false,所以不能推荐任何东西。

    4. 不确定这是否是您的意思,但keepSynced(true) 在应用程序运行之间不会持续存在。因此,每次您的应用/视图启动时,您都必须致电 keepSynced(true)

    5. 见上文...

    一般来说,您似乎通过以不同方式调用 API 来尝试绕过 API 的工作方式。我通常不会从中看到很好的结果。如果您希望应用的行为与 API 不同,请考虑创建自定义包装器,并在其中缓存数据。

    【讨论】:

    • 您好弗兰克,感谢您的回复。我有点困惑:你说 keepSynced 会同步最后 25 个子节点。当我在观察帖子的页面中时,这是真的 - 它会实时更新。但是,在刷新应用程序(关闭和重新打开)时,引用无法正确同步最后 25 个节点并加载过时数据。
    • 既然你问keepSynced() 是如何工作的,我回答了你所有的问题。如果您看到的行为与(您认为的)API 应该如何工作不匹配,请编辑您的问题以包含 minimal, complete/standalone code with which anyone can reproduce that problem。这是知道我们正在查看相同的行为和代码的唯一方法。这里的独立意味着:1) 尽可能使用硬编码值,2) 日志输出,而不是 UI。
    • 感谢弗兰克提供的信息,因为当时我在车里,所以我没有仔细看答案。只是为了澄清-我调用 keepSynced(false) 以便节点不会在我不需要它们的页面之外保持同步。除非我误解了什么,否则我认为保持 keepSynced 为真会浪费带宽。在问题 #4 中,进入后台是指将应用程序保持在后台,但不会终止进程并转到其他应用程序。
    • 更新:我解决了我的问题。事实证明,Firebase 实际上并没有返回过时的数据。它返回了正确的数据,但我的查询是基于所有自动生成的键都按某种顺序预先排序的假设。事实证明他们不是。
    • 很高兴听到您发现问题 Catas!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 2013-04-06
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多