将 Cloud Firestore 和 Firebase 实时数据库配合使用

您可以在应用中同时使用 Firebase 实时数据库和 Cloud Firestore,并利用每种数据库解决方案的优势来满足您的需求。例如,您可能希望利用实时数据库对在线状态的支持,如在 Cloud Firestore 中构建在线状态系统中所述。

详细了解不同数据库之间的差异

将数据移至 Cloud Firestore

如果您已决定要将部分数据从实时数据库迁移到 Cloud Firestore,请考虑以下流程。由于每种数据库都有独特的需求和结构方面的注意事项,因此没有自动迁移途径。不过,您可以按照以下常规步骤进行操作:

  1. 将数据结构和安全规则从实时数据库映射到 Cloud Firestore。 实时数据库和 Cloud Firestore 均依赖于 Firebase 身份验证,因此您无需为您的应用更改用户身份验证机制。不过,由于安全规则和数据模型有所不同,因此在开始将数据迁移到 Cloud Firestore 之前,请务必仔细考虑这些差异。

  2. 移动历史数据。 在 Cloud Firestore 中设置新的数据结构时,您可以将现有的数据从实时数据库映射并移动到新的 Cloud Firestore 实例。但是,如果要在应用中同时使用这两种数据库,则无需将历史数据从实时数据库中移出。

  3. 将新数据实时镜像到 Firestore。 将新数据添加到实时数据库的同时使用 Cloud Functions 将其写入新的 Cloud Firestore 数据库。

  4. 将 Cloud Firestore 作为迁移后的数据的主要数据库。 迁移部分数据后,请将 Cloud Firestore 作为主要数据库来使用,且在处理迁移后的数据时减少实时数据库的使用。请将仍与实时数据库绑定的应用版本纳入考虑范围以使用相关数据,并思考一下您打算如何继续为其提供支持。

请确保同时考虑实时数据库Cloud Firestore结算费用

映射您的数据

实时数据库中的数据结构采用单树结构,而 Cloud Firestore 则通过文档、集合和子集合支持更明晰的数据层次结构。如果您将部分数据从实时数据库移动到 Cloud Firestore,可以考虑针对您的数据采用一种不同的体系结构。

要考虑的主要差异

如果您将数据从现有的实时数据库树移动到 Cloud Firestore 文档和集合,请注意数据库之间的以下主要差异(这些差异可能会影响在 Cloud Firestore 中设置数据结构的方式):

  • 浅查询可在分层数据结构中提供更高的灵活性。
  • 复杂查询能够实现更高的细化程度,并减少对重复数据的需求。
  • 查询游标可提供更强大的分页功能。
  • 事务不再要求所有数据共用一个根,并且效率更高。
  • 实时数据库和 Cloud Firestore 的结算费用会有所不同。在很多情况下,Cloud Firestore 可能比实时数据库的费用更高,尤其是在依赖大量小操作时。您可以考虑减少对数据库的操作次数,并避免不必要的写入。详细了解实时数据库和 Cloud Firestore 在结算方面的差异。

最佳做法的实际运用

以下示例反映了您在数据库之间迁移数据时可能会考虑的一些注意事项。相比您使用实时数据库可能采用的数据结构,您可以利用浅表读取和经过改进的查询功能,获得更自然的数据结构。

我们假设有一个城市指南应用,该应用旨在帮助用户寻找世界上各个城市的知名地标。由于实时数据库缺少浅表读取功能,因此您可能必须使用两个顶级节点来设置数据结构,如下所示:

// /cities/$CITY_KEY
{
  name: "New York",
  population: 8000000,
  capital: False
}

// /city-landmark/$CITY_KEY/$LANDMARK_KEY
{
  name: "Empire State Building",
  category: "Architecture"
}

Cloud Firestore 具有浅表读取功能,因此查询集合中的文档不会从子集合中提取数据。这样,您就可以在子集合中存储地标信息:

// /cities/$CITY_ID
{
  name: "New York",
  population: 8000000,
  capital: False,
  landmarks: [... subcollection ...]
}

文档的大小上限为 1MB,因此每个城市的文档都不能过大(您应避免在文档中嵌套列表,造成文档臃肿),这也是将地标存储为子集合的另一个原因。

Cloud Firestore 的高级查询功能可减少常见访问模式造成的重复数据需求。例如,假设此城市指南应用中的某个界面显示了按人口数量排序的所有首都城市。在实时数据库中,实现这一点的最有效方式是维护一个单独的首都城市列表,该列表中的数据与 cities 列表中的数据会有重复,如下所示:

{
   cities: {
    // ...
   },

   capital-cities: {
     // ...
   }
}

在 Cloud Firestore 中,您可以将按照人口数量排序的首都城市列表表示为一个查询:

db.collection('cities')
    .where('capital', '==', true)
    .orderBy('population')

请详细了解 Cloud Firestore 数据模型并参阅我们的解决方案,以获取有关如何设计 Cloud Firestore 数据库结构的更多提示。

保护您的数据

无论您使用的是适用于 Android、iOS 或网页客户端的 Cloud Firestore 安全规则,还是适用于服务器的 Identity Access Management (IAM),都要确保您在 Cloud Firestore 以及实时数据库中的数据安全无虞。这两种数据库的用户身份验证都由 Firebase 身份验证处理,因此您无需在开始使用 Cloud Firestore 时更改身份验证的实现机制。

要考虑的主要差异

  • 移动 SDK 和网页 SDK 使用 Cloud Firestore 安全规则来保护数据,而服务器 SDK 则使用 Identity Access Management (IAM) 来保护数据。
  • Cloud Firestore 安全规则不会进行级联,除非您使用通配符。文档和集合不会以其他方式沿用规则。
  • 您不再需要(像在实时数据库中那样)单独验证数据。
  • Cloud Firestore 会在执行查询之前检查规则,以确保用户对查询返回的所有数据拥有相应的访问权限。

将历史数据移动到 Cloud Firestore

将数据和安全结构映射到 Cloud Firestore 的数据和安全模型后,您便可以开始添加数据了。如果您打算在将应用从实时数据库迁移到 Cloud Firestore 之后查询历史数据,请将导出的旧数据添加到新的 Cloud Firestore 数据库。如果您打算在应用中同时使用实时数据库和 Cloud Firestore,则可以跳过此步骤。

为避免新数据被旧数据覆盖,您可能需要先添加历史数据。如果您同时向这两种数据库添加新数据(如下一步所述),请确保优先处理 Cloud Functions 添加到 Cloud Firestore 的新数据。

要将历史数据迁移到 Cloud Firestore,请执行以下操作:

  1. 从实时数据库导出您的数据或使用近期的备份
    1. 转到 Firebase 控制台中的“数据库”部分
    2. 数据标签中选择数据库的根级节点,然后从菜单中选择导出 JSON
  2. 在 Cloud Firestore 中创建新的数据库并添加数据

    在将部分数据移动到 Cloud Firestore 时,请考虑采用以下策略:

    • 编写一个自定义脚本来迁移您的数据。由于每个数据库都有独特的需求,因此我们无法提供此脚本的模板,但我们的 Slack 频道Stack Overflow 上的 Cloud Firestore 专家可以检查您的脚本或针对您的具体情况提供建议。
    • 使用服务器 SDK(Node.js、Java、Python 或 Go)将数据直接写入 Cloud Firestore。如需了解如何设置服务器 SDK,请参阅使用入门
    • 要加快大量数据迁移的速度,可使用批量写入操作,并在单个网络请求中发送多达 500 项操作。
    • 要使速度保持在 Cloud Firestore 的速率限制以下,可将操作速率限制为每个集合每秒 500 次写入。

向 Cloud Firestore 添加新数据

要保持数据库之间的数据对等性,请向两种数据库中实时添加新数据。请使用 Cloud Functions 在客户端向实时数据库写入数据时触发向 Cloud Firestore 写入数据的操作。您需要确保 Cloud Firestore 优先处理来自 Cloud Functions 的新数据,而不是优先处理为进行历史数据迁移而进行的数据写入。

请创建一个函数,用于每次客户端向实时数据库写入数据时,将新数据或更改的数据写入 Cloud Firestore。详细了解适用于 Cloud Functions 的实时数据库触发器

将 Cloud Firestore 作为迁移后的数据的主要数据库

如果您决定将 Cloud Firestore 作为部分数据的主要数据库,请务必考虑您已设置的所有数据镜像功能,并验证您的 Cloud Firestore 安全规则。

  1. 如果您使用 Cloud Functions 来维持数据库之间的数据对等性,请务必避免在循环中向两种数据库都写入数据。请将您的函数改为只向一种数据库写入数据,或者完全移除该函数并在与实时数据库绑定的应用中逐步弃用写入功能。您在这方面的取舍取决于您自己的具体需求和用户。

  2. 验证您的数据是否得到了适当的保护。您需要验证您的 Cloud Firestore 安全规则或 IAM 设置。

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面