欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

适用于Android的Cloud Firestore入门

程序员文章站 2022-04-07 19:46:55
...

Cloud Firestore是Firebase产品家族的最新成员。 尽管仍处于测试阶段,但Google已经将其作为Firebase实时数据库的一种更灵活,功能更丰富的替代方案进行了展示。

如果您曾经使用过实时数据库,则可能会意识到它实际上是一个大型JSON文档,最适合仅存储简单的键值对。 尽管有可能,但高效,安全地将分层数据存储在其中非常麻烦,并且需要一种经过深思熟虑的策略,该策略通常涉及尽可能地扁平化数据或对数据进行非规范化。 如果没有这种策略,对实时数据库的查询可能会消耗不必要的大量带宽。

Cloud Firestore更类似于MongoDB和CouchDB等面向文档的数据库,没有此类问题。 而且,它具有大量非常方便的功能,例如对批处理操作,原子写入和索引查询的支持。

在本教程中,我将帮助您开始在Android平台上使用Cloud Firestore。

先决条件

要遵循本教程,您需要:

  • 最新版本的Android Studio
  • 一个Firebase帐户
  • 以及运行Android 4.4或更高版本的设备或模拟器

1.创建Firebase项目

在Android应用中使用Firebase产品之前,必须在Firebase 控制台中为其创建一个新项目。 为此,请登录到控制台,然后在欢迎屏幕中按添加项目按钮。

适用于Android的Cloud Firestore入门

在弹出的对话框中,为项目指定一个有意义的名称,可以选择为其指定一个有意义的ID,然后按“ 创建项目”按钮。

适用于Android的Cloud Firestore入门

创建项目后,可以通过导航到“ 开发”>“数据库”并按“ 尝试Firestore Beta”按钮来将Firestore设置为其数据库。

适用于Android的Cloud Firestore入门

在下一个屏幕中,确保选择“ 以测试模式启动”选项,然后按“ 启用”按钮。

适用于Android的Cloud Firestore入门

此时,您将拥有一个空的Firestore数据库,准备在您的应用程序中使用它们。

适用于Android的Cloud Firestore入门

2.配置Android项目

您的Android Studio项目仍然对您在上一步中创建的Firebase项目一无所知。 在两者之间建立连接的最简单方法是使用Android Studio的Firebase Assistant。

转到工具> Firebase以打开助手。

适用于Android的Cloud Firestore入门

由于Firestore仍处于测试阶段,因此Assistant尚不支持它。 不过,通过将Firebase Analytics添加到您的应用中,您将能够自动执行大多数必需的配置步骤。

首先单击“ 分析”部分下的“ 记录分析事件”链接,然后按“ 连接到Firebase”按钮。 现在,应该会弹出一个新的浏览器窗口,询问您是否要允许Android Studio管理Firebase数据。

适用于Android的Cloud Firestore入门

按“ 允许”按钮继续。

返回Android Studio,在弹出的对话框中,选择“ 选择现有Firebase或Google项目”选项,选择您之前创建的Firebase项目,然后按“ 连接到Firebase”按钮。

适用于Android的Cloud Firestore入门

接下来,按“ 将Analytics(分析)添加到您的应用程序”按钮,将Firebase核心依赖项添加到您的项目中。

最后,要将Firestore添加为implementation依赖项,请在app模块的build.gradle文件中添加以下行:

implementation 'com.google.firebase:firebase-firestore:11.8.0'

不要忘记按立即同步按钮以完成配置。 如果在同步过程中遇到任何版本冲突错误,请确保Firestore依赖项和Firebase Core依赖项的版本相同,然后重试。

3.了解文件和馆藏

Firestore是NoSQL数据库,可让您以类似JSON的文档形式存储数据。 但是,存储在其上的文档不能独立存在。 它必须始终属于一个集合。 顾名思义,集合不过是一堆文件而已。

集合中的文档显然是同级的。 但是,如果要在它们之间建立父子关系,则必须使用子集合。 子集合只是属于文档的集合。 默认情况下,文档自动成为属于其子集合的所有文档的父级。

还值得注意的是,Firestore自己管理集合和子集合的创建和删除。 每当您尝试将文档添加到不存在的集合时,它都会创建该集合。 同样,从集合中删除所有文档后,它也会删除它。

4.创建文件

为了能够从您的Android应用程序写入Firestore数据库,您必须首先通过调用FirebaseFirestore类的getInstance()方法获取对该数据库的引用。

val myDB = FirebaseFirestore.getInstance()

接下来,您必须通过调用collection()方法来创建新集合或获取对现有集合的引用。 例如,在空数据库上,以下代码创建一个名为solar_system的新集合:

val solarSystem = myDB.collection("solar_system")

一旦有了对集合的引用,就可以通过调用其add()方法开始向其中添加文档,该方法需要将map作为其参数。

// Add a document
solarSystem.add(mapOf(
        "name" to "Mercury",
        "number" to 1,
        "gravity" to 3.7
))

// Add another document
solarSystem.add(mapOf(
        "name" to "Venus",
        "number" to 2,
        "gravity" to 8.87
))

add()方法自动生成唯一的字母数字标识符,并将其分配给它创建的每个文档。 如果希望文档具有自己的自定义ID,则必须首先通过调用document()方法手动创建这些文档,该方法将唯一的ID字符串作为其输入。 然后,您可以通过调用set()方法填充文档,该方法与add方法一样,希望将地图作为其唯一参数。

例如,以下代码创建并填充一个名为PLANET_EARTH的新文档:

solarSystem.document("PLANET_EARTH")
        .set(mapOf(
                "name" to "Earth",
                "number" to 3,
                "gravity" to 9.807
        ))

如果您转到Firebase控制台并查看数据库的内容,则可以轻松发现自定义ID。

适用于Android的Cloud Firestore入门

请注意,如果数据库中已经存在传递给document()方法的自定义ID,则set()方法将覆盖关联文档的内容。

5.创建子集合

对子集合的支持是Firestore最强大的功能之一,正是这一点使其与Firebase实时数据库明显不同。 使用子集合,您不仅可以轻松地将嵌套结构添加到数据中,还可以确保查询将消耗最少的带宽。

创建子集合与创建集合非常相似。 您需要做的就是在DocumentReference对象上调用collection()方法,并将一个字符串传递给该对象,该字符串将用作子集合的名称。

例如,以下代码创建一个名为satellites的子集合,并将其与PLANET_EARTH文档相关联:

val satellitesOfEarth = solarSystem.document("PLANET_EARTH")
                                   .collection("satellites")

一旦引用了一个子集合,就可以调用add()set()方法向其中添加文档。

satellitesOfEarth.add(mapOf(
        "name" to "The Moon",
        "gravity" to 1.62,
        "radius" to 1738
))

运行上述代码后,在Firebase控制台中, PLANET_EARTH文档将如下所示:

适用于Android的Cloud Firestore入门

6.运行查询

如果您知道要读取的文档的ID,则对Firestore数据库执行读取操作非常容易。 为什么? 因为您可以通过调用collection()document()方法直接获取对文档的引用。 例如,以下是如何获取对属于solar_system集合的PLANET_EARTH文档的引用:

val planetEarthDoc = myDB.collection("solar_system")
                         .document("PLANET_EARTH")

要实际读取文档的内容,必须调用异步get()方法,该方法返回Task 通过OnSuccessListener添加OnSuccessListener ,可以在读取操作成功完成时得到通知。

读取操作的结果是一个DocumentSnapshot对象,该对象包含文档中存在的键值对。 通过使用其get()方法,可以获得任何有效键的值。 以下示例显示了如何:

planetEarthDoc.get().addOnSuccessListener {
    println(
       "Gravity of ${it.get("name")} is ${it.get("gravity")} m/s/s"
    )
}

// OUTPUT:
// Gravity of Earth is 9.807 m/s/s

如果您不知道要阅读的文档ID,则必须在整个集合上运行传统查询。 Firestore API提供了直观命名的过滤器方法,例如whereEqualTo()whereLessThan()whereGreaterThan() 由于筛选器方法可以返回多个文档作为其结果,因此您将需要在OnSuccessListener循环以处理每个结果。

例如,要获取我们在先前步骤中添加的金星行星的文档内容,可以使用以下代码:

myDB.collection("solar_system")
  .whereEqualTo("name", "Venus") 
  .get().addOnSuccessListener {
      it.forEach {
        println(
          "Gravity of ${it.get("name")} is ${it.get("gravity")} m/s/s"
        )
      }
  }

// OUTPUT:
// Gravity of Venus is 8.87 m/s/s

最后,如果您有兴趣阅读属于集合的所有文档,则可以直接在集合上调用get()方法。 例如,这是您可以列出solar_system集合中存在的所有行星的solar_system

myDB.collection("solar_system")
        .get().addOnSuccessListener {
            it.forEach {
                println(it.get("name"))
            }
        }

// OUTPUT:
// Earth
// Venus
// Mercury

请注意,默认情况下,返回结果没有确定的顺序。 如果要基于所有结果中都存在的键对它们进行排序,则可以使用orderBy()方法。 以下代码根据number键的值对结果进行排序:

myDB.collection("solar_system")
                .orderBy("number")
                .get().addOnSuccessListener {
            it.forEach {
                println(it.get("name"))
            }
        }

// OUTPUT:
// Mercury
// Venus
// Earth

7.删除数据

要删除具有已知ID的文档,您要做的就是获取对该文档的引用,然后调用delete()方法。

myDB.collection("solar_system")
    .document("PLANET_EARTH")
    .delete()

删除多个文档(作为查询结果而获得的文档)会稍微复杂一些,因为没有内置方法可以执行此操作。 您可以遵循两种不同的方法。

最简单,最直观的方法(尽管仅适用于非常少量的文档)是循环搜索结果,获取每个文档的引用,然后调用delete()方法。 这是使用该方法删除solar_system集合中所有文档的solar_system

myDB.collection("solar_system")
        .get().addOnSuccessListener {
            it.forEach {
                it.reference.delete()
            }
        }

一种更有效和可扩展的方法是使用批处理操作。 批处理操作不仅可以原子删除多个文档,还可以大大减少所需的网络连接数。

若要创建新批处理,必须调用数据库的batch()方法,该方法返回WriteBatch类的实例。 然后,您可以遍历查询的所有结果,并将它们传递给WriteBatch对象的delete()方法,以将其标记为删除。 最后,要真正开始删除过程,可以调用commit()方法。 以下代码向您展示了如何:

myDB.collection("solar_system")
        .get().addOnSuccessListener {

    // Create batch
    val myBatch = myDB.batch()

    // Add documents to batch
    it.forEach {
        myBatch.delete(it.reference)
    }

    // Run batch
    myBatch.commit()
}

请注意,尝试在单个批处理操作中添加太多文档会导致内存不足错误。 因此,如果您的查询可能返回大量文档,则必须确保将它们分成多个批次

结论

在此入门教程中,您学习了如何在Google Cloud Firestore上执行读写操作。 我建议您立即开始在Android项目中使用它。 将来很有可能会取代实时数据库。 实际上,谷歌已经说过,到测试版发布时,它将比实时数据库更加可靠和可扩展。

要了解有关Cloud Firestore的更多信息,可以参考其官方文档

翻译自: https://code.tutsplus.com/tutorials/getting-started-with-cloud-firestore-for-android--cms-30382