Realm 与 Firestore 上的大型集合同步 - 架构问题/问题

2024-03-13

我在 Firestore 集合中有一个产品对象集合(标题、描述、价格、定量、urlString 等)。目前大约有 1000 件商品,但可能会达到 10k。在我的 iOS 应用程序启动时,我设置了一个集合侦听器(db.collection("products").rx.listen())然后将更改保存到本地领域数据库。

.subscribe(onNext: { querySnapshot in
     querySnapshot.documentChanges.forEach { docChange in
                autoreleasepool {
                    let realm = try! Realm(configuration: Realm.Configuration.defaultConfiguration)
                    let newData = docChange.document.data()
                    if let item = itemFactory.createItem(using: newData) {
                        if (docChange.type == .added) {
                            //realm.add(item)
                        }
                        if (docChange.type == .modified) {
                            //realm.update(item)
                        }
                        if (docChange.type == .removed) {
                            //realm.delete(item)
                        }
                    }
                }
            }
        }, onError: { error in
            print("Error fetching snapshots: \(error)")
        }).disposed(by: disposeBag)

我已经详细阅读了 firestore 文档,但我不是 100% 相信这种方法是可靠的或高性能的。

问题:当应用程序启动时,Firestore 每次都会下载所有 10k 文档,然后再描述更改吗?或者它会在第一次缓存所有 10k,然后仅在后续启动时下载更改。我确信一旦更改事件触发,所有后续事件将仅获取对 Firestore 数据库的更改。我担心的是,当应用程序启动时首次订阅侦听器,它会下载所有 10k 项(这将是昂贵的)。

2019 年 1 月 9 日编辑:

我最终实现了 @zavtra 优雅的答案,代码大致如下:

var newestUpdatedAt = UserDefaults.standard.double(forKey: kUDItemUpdatedAt)
//...
db.collection(kProducts)
            .whereField(kUpdatedAt, isGreaterThan: newestUpdatedAt)
            .rx.listen()
//...

querySnapshot.documentChanges.forEach { docChange in
            autoreleasepool {
                let realm = try! Realm(configuration: Realm.Configuration.defaultConfiguration)
                let newData = docChange.document.data()
                if let item = itemFactory.createItem(using: newData) {
                    if item.updatedAt > newestUpdatedAt {
                       newestUpdatedAt = item.updatedAt
                    }
                    if (docChange.type == .added) {
                        //realm.add(item)
                    }
                    if (docChange.type == .modified) {
                        //realm.update(item)
                    }
                    if (docChange.type == .removed) {
                        //realm.delete(item)
                    }
                }
            }
        }
        UserDefaults.standard.set(newestUpdatedAt, forKey: kUDItemUpdatedAt)

根据文档:

docChanges 返回自上次以来文档更改的数组 快照。如果这是第一个快照,则所有文档都将位于 列为“添加”更改。

每次重新启动应用程序都会触发此“第一个快照”行为。如果您想解决此行为,您必须:

  1. 检索本地保存的最新文档及其时间戳。
  2. 构建一个查询,其中所有文档都从该时间戳开始(即每个文档的时间戳至少是最近保存的时间戳)
  3. 订阅应用程序条目上该查询的更改。

为此,您必须向每个文档添加一个时间戳字段,并在时间戳字段上的 firestore 规则中添加一个“indexOn”规则,以防止客户端下载和排序整个集合。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Realm 与 Firestore 上的大型集合同步 - 架构问题/问题 的相关文章

随机推荐

  • 设置一堆简短/友好的重定向 URL

    我需要设置数百个遵循以下格式的短重定向 URL http mysite com shorturl 这将重定向到 http mysite com index php id N 其中 N 是与该快捷方式对应的 ID 执行此操作的最佳方法是什么
  • 查找字符和数字之间可能的双射

    假设您有一个字符串 S 和列表 L 中的一个数字序列 使得 len S len L 检查是否可以找到字符串的字符与序列中的数字之间的双射以使每个字符与一个且仅一个数字匹配的最干净的方法是什么 例如 aabbcc 应与 115522 匹配 但
  • 为动态创建的 HTML 元素创建事件监听器

    在 downMouseBtn event 事件处理程序中 我创建了元素 div 我需要为创建的项目创建一个事件监听器 我怎样才能创建这个 添加哪部分代码呢 我需要处理动态生成的项目的 mouseClick 事件 import Compone
  • 字符串中回文子序列的总数

    问题是这样的 对于作为输入给出的每个字符串 您需要告诉它的回文子序列的数量 不一定是不同的 请注意 空字符串不是回文 例如 aab 的回文子序列是 a a b aa 该方法返回 4 我心中有寻找最长回文子序列的动态规划解决方案 因此尝试从中
  • Reactive Cocoa 5 和 ReactiveSwift 网络请求处理

    我试图弄清楚是否可以使用 ReactiveSwift 和 RAC5 来实现适合我需求的网络请求处理 在主题下从 RACSignal 迁移到 ReactiveSwift 或 RAC5 https stackoverflow com quest
  • 如何在没有结构体实例的情况下调用特征方法?

    如果我有一个结构体 其方法没有self作为参数 我可以通过调用该方法SomeStruct method 我似乎无法对从特征定义的方法做同样的事情 例如 trait SomeTrait fn one trait gt uint struct
  • 未知提供商 CookieStore

    我正在提供服务 我想使用 cookieStore 模块 它工作正常 但是当单元测试时它会中断 并给出错误 cookieStoreProvider 该服务如下所示 serviceModule factory filtersService ro
  • 如何将 --relative 与 git format-patch 一起使用?

    当我使用git diff relative HEAD HEAD 我得到了一些不错的补丁输出 我删除了它所在目录之外的路径 我开始使用git format patch我也想用 relative但没有看到任何选项 我怎样才能得到同样的效果 Th
  • 从空 Swift 数组中获取对象类型

    有没有办法从空数组中获取数组元素的实例 我需要dynamic属性 因为我使用了一些 KVC 方法NSObject import Foundation class BaseClass NSObject func myFunction doWo
  • 如何获取 Python 字符串中括号内的值? [复制]

    这个问题在这里已经有答案了 我有这样的事情 a 2 3 4 b 12 3 5 我只想要括号内的值 我使用正则表达式 它有效 但我的老师不允许 我怎样才能做到这一点 gt gt gt a 2 3 4 gt gt gt a a index 1
  • C语言——调用没有函数原型的函数

    I found here http opencbp sourceforge net en US ISO8859 1 books opencbook func prototypes html如果函数位于函数调用之下 则函数原型在函数调用之前是
  • Python tk框架

    我有生成以下错误的 python 代码 objc 36554 Class TKApplication is implemented in both Library Frameworks Tk framework Versions 8 5 T
  • 如何禁用文本小部件的输入但允许编程输入?

    我该如何锁定一个Text小部件 以便用户只能选择并从中复制文本 但我仍然可以将文本插入到Text来自函数或类似函数 您是否尝试过简单地禁用文本小部件 text widget configure state disabled 在某些平台上 您
  • 长时间运行 RTS 游戏多人注意事项

    我正在开发一款实时太空策略游戏克隆游戏 该游戏当时没有任何多人游戏选项 我想添加多人游戏 游戏本身的时间比较长 大约需要10 15小时才能通关 这很长 我不想强 迫玩家不间断地玩它或由于崩溃 断电而失去游戏状态 类似的游戏是如何解决此类问题
  • 格式化代码片段以在 Blogger 上写博客 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我的博客托管在 Blogger 上 我经常在以下位置发布代码片段C C Java XML等等 但我发现该片段被 损坏 是否有任何网站可以用来预先解析代
  • helper' aria-label=''####' 的未定义方法 `merge':string <%= form_for %> helper'> '####' 的未定义方法 `merge':string <%= form_for %> helper

    我有一个表单 当发布时 会呈现另一个表单 我想做的是将第一个表单中的参数传递到第二个表单的某些隐藏字段中 第二种表单使用 form for 表单助手 我想做的是让它接受发布给它的参数 表格如下所示 div class found l div
  • Facebook 开放图私人群组提要请求

    我想从图形 api 获取数据 特别是我尝试从组中获取时间线 例如 让我们看一下 Facebook 开发人员概述中提供的请求 https graph facebook com 195466193802264 https graph faceb
  • (int)、Convert.ToInt32(x) 或 Int32.Parse(x) 哪个最快?

    以下哪段代码对于转换某些对象 x 是最快 最佳实践 int myInt int x or int myInt Convert ToInt32 x or int myInt Int32 Parse x 或者在字符串 s 的情况下 int my
  • 将 .NET 表达式树链接到新程序集中

    我正在尝试编写自己的玩具 My Toy Language gt MSIL 编译器 以便更好地了解编译器的工作原理 我的解析和词法分析工作正常 我已经构建了表达式树并使用 System Linq Expressions 表达式树 API 我有
  • Realm 与 Firestore 上的大型集合同步 - 架构问题/问题

    我在 Firestore 集合中有一个产品对象集合 标题 描述 价格 定量 urlString 等 目前大约有 1000 件商品 但可能会达到 10k 在我的 iOS 应用程序启动时 我设置了一个集合侦听器 db collection pr