【问题标题】:What is the best way to store history of data in Firebase Realtime Database?在 Firebase 实时数据库中存储数据历史的最佳方式是什么?
【发布时间】:2021-03-22 02:18:01
【问题描述】:

我正在使用 Firebase 实时数据库构建一个应用。此应用程序的用户将能够创建帖子并随时对其进行编辑。此外,他们可以访问帖子的所有版本,但默认情况下他们会获得最新版本。到目前为止我已经得到了这个:

Realtime Database-root
   |
   --- posts
        |
        --- postId
                 |
                 --- versionId
                 |           |
                 |           --- uid
                 |           |
                 |           --- title
                 |           |
                 |           --- date
                 |           
                 --- versionId
                             |
                             --- uid
                             |
                             --- title
                             |
                             --- date

但是,恐怕这是最好的方法。考虑到成本、可扩展性、安全性和性能,这种方法是否可以改进?

【问题讨论】:

  • 如果帖子是纯文本格式,您只能存储diff。意思是 GNU 差异。如有必要,应用补丁以向用户显示完整的文本。

标签: firebase firebase-realtime-database firebase-security


【解决方案1】:

由于 RTDB 的存储成本为每 GB 5 美元,因此我建议您使用 Google Storage 作为廉价数据存储来存储您的版本。

这意味着您的数据库应该像这样存储帖子:

Realtime Database-root
   |
   --- posts
        |
        --- postId
                 |
                 --- uid
                 |
                 --- title
                 |
                 --- date
   --- postsVersions
        |
        --- postId
                 |
                 --- version1Id: true
                 |
                 --- version2Id: true

version1Idversion2Id 引用存储在 Google Storage 中的 JSON 文档。

工作流程

  1. 用户创建初始帖子并创建数据库条目。

  2. 用户进行更改并将其保存到 RTDB,覆盖 /posts 中的先前版本。

  3. /posts/{postId} 上的onUpdate() 事件上触发的云函数采用以前的版本并将其作为https://storage.google.com/<bucket>/<postId>/<version1Id>.json 保存到Google 存储,并将该版本ID 保存到/postsVersions

  4. 如果用户从该/postsVersions 中删除version1Id 键,则监视/postsVersions/{postId} 上的onDelete() 事件的云函数应从Google 存储中删除该JSON 文件。

  5. 最后,如果用户想要加载以前版本的帖子,他们会发出一个简单的 HTTPS 请求以从 Google 存储中检索 JSON 文件,然后将 /posts 更新为以前的版本。

安全

您应该确保您的版本 ID 不可猜测且不连续,然后您可以使用 IAM 权限为所有经过身份验证的用户简单地提供对存储桶的全面访问权限。为了更精细地控制用户无法访问其他用户的版本化帖子,非公共存储桶和生成签名 URL 的 API 端点将很容易实现。

【讨论】:

  • 为清楚起见,实时数据库在付费 Blaze plan 上为 5Gb,而免费计划提供 1Gb;即使存储了旧版本,1Gb 也是很多帖子。此外,如果您指的是在Cloud Storage 中存储 JSON,这可能会出现问题,因为这通常不是目的(尽管可以这样做),因为 RTDB 无法像 JSON 那样查询/读取它 Cloud Storage 是为应用程序构建的需要存储和提供用户生成内容(例如照片或视频)的开发人员。也许这不是问题?
  • 我喜欢这个想法,但我也同意@Jay。云存储可能不适合这种情况,因为即使一切正常,这里也存在安全问题。云存储的安全规则仅限于其自身用途。如果没有访问实时数据库,就无法检查用户权限。
  • @StewieGriffin 几年来,我使用 GCS 运行亚马逊价格跟踪器,以类似的方法存储和检索历史价格数据,并且从未超出免费套餐。如果您想保持低成本,我强烈推荐这是一个可行、可扩展且具有成本效益的解决方案。您可以通过使用无法猜测的版本名称或什至提供对象的签名 URL 的简单 API 端点来解决安全问题。
  • @Jay “如果您指的是在 Cloud Storage 中存储 JSON 可能会出现问题,因为这通常不是目的” 我不确定您从哪里采购从,我在一个非常繁忙的网站上做了类似的事情,它的扩展性非常好。 “RTDB 无法将它作为 JSON 进行查询/读取” 如果客户端想要还原,则不需要这样,他们从 GCS 下载该特定版本,然后将 JSON 推送到 RTDB正常更新。
  • 我并不是说它不能完成,只是官方文档中所述的主要意图更多的是针对 blob 类型的数据。我是从官方文档Storage 中获取的。我只是想弄清楚用例,因为它无法查询。例如如果您想查询特定帖子的“存档”,则此实现无法实现。但是,如果它是一个还原,那么肯定 - 它会起作用。只需为一个好的答案添加更多信息。
猜你喜欢
  • 1970-01-01
  • 2010-09-22
  • 2018-06-16
  • 1970-01-01
  • 2020-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多