适用于Android的Cloud Firestore入门

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

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

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

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

先决条件

要遵循本教程,您需要:

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

1.创建Firebase项目

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

Firebase控制台的欢迎屏幕

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

添加项目对话框

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

数据库选择页面

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

Firestore安全性配置页面

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

空的Firestore数据库

2.配置Android项目

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

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

Firebase助手窗口

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

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

Android Studio请求权限

按“ 允许”按钮继续。

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

连接到Firebase对话框

接下来,按“ 将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。

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文档将如下所示:

文件的子集合

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值