该文档是关于COMP5216移动计算课程Lab 04的实验指导,主要目标是学习如何使用Google的Firebase平台开发移动应用,以及使用Cloud Firestore存储和读取数据。具体任务包括连接应用到Firebase并配置Cloud Firestore、向Cloud Firestore写入数据、从Cloud Firestore显示数据、在Cloud Firestore中对数据进行排序和过滤。文档详细介绍了每个任务的具体步骤和相关代码。
2024年第二学期
Lab 04 – 云服务
目标: 1. 学习如何使用Google的Firebase平台开发移动应用。 2. 理解如何使用Cloud Firestore存储和读取数据。
任务: 1. 连接应用到Firebase并配置Cloud Firestore。 2. 向Cloud Firestore写入数据。 3. 从Cloud Firestore显示数据。 4. 在Cloud Firestore中对数据进行排序和过滤。
计算机科学学院
第1页,共13页
COMP5216移动计算
LabW04
到目前为止,我们已经学习了移动应用如何在手机本地保存数据(参考Lab Week 03)。但这并不允许其他客户端(如另一个应用或网站)访问这些数据。
本教程改编自Cloud Firestore Android Codelab,向您展示如何将移动应用连接到Cloud Firestore(Google为移动和网络应用提供的云端NoSQL数据库),并从中查询数据。您将学习如何构建一个由Cloud Firestore支持的餐厅推荐应用,名为“Friendly Eats”。此外,您还将学习如何: • 将您的应用连接到Google的Firebase平台并配置Cloud Firestore。 • 从Android应用向Cloud Firestore读写数据。 • 实时监听Firestore数据的变化。 • 使用基本的Firebase身份验证。
注意:本教程使用免费的Spark计划,对于大多数应用的开发目的来说已经足够。
任务1:连接应用到Firebase并配置Cloud Firestore 1. 使用您的Google账户登录Firebase控制台。 2. 在Firebase控制台上,点击“添加项目”。 您的Firebase项目 添加项目 3. 在“创建项目(步骤1/3)”中,为您的Firebase项目输入一个名称,例如“Friendly Eats”。点击“继续”。 4. 在步骤2/3“您的Firebase项目的Google Analytics”中,选择“为这个项目启用Google Analytics”。点击“继续”。 5. 在步骤3/3“配置Google Analytics”中,选择“创建一个新账户”,输入“COMP5216”作为新的Google Analytics账户名称。点击“保存”。 6. 将“Analytics位置”选项保留为“美国”,并保留“使用默认设置共享Google Analytics数据”的默认选项。 7. 接受Google Analytics条款。 8. 点击“创建项目”。 9. 大约一分钟后,您的Firebase项目将准备就绪。点击“继续”。 10. 从Canvas下载并解压为Fire Eats应用提供的示例基础代码:“friendlyeats – android.zip”。解压后,您的机器上应该会创建一个文件夹“friendlyeats – android”。您也可以直接从GitHub下载示例代码。 11. 将项目导入到Android Studio中。您可能会看到一些编译错误或关于缺少google – services.json文件的警告。 12. 在Firebase控制台上,选择左侧导航中的“项目概述”。通过点击Android按钮选择平台,开始将Firebase添加到您的应用中。当提示输入Android包名称时,使用“com.google.firebase.example.fireeats”。 通过添加Firebase开始您的应用 iOS 添加一个应用开始 13. 点击“注册应用”,并按照说明下载“google – services.json”配置文件,并将其移动到您的Android应用代码的app/文件夹中。点击“下一步”。 14. 按照说明通过修改您的build.gradle文件来添加Firebase SDK依赖项,以使用Google服务插件: • 项目级build.gradle(
计算机科学学院
第2页,共13页
COMP5216移动计算
LabW04
Y1 Friendly Eats
任务2:向Cloud Firestore写入数据 在这个任务中,我们将向Cloud Firestore写入一些数据,以便填充当前为空的主屏幕。您可以在Firebase控制台中手动输入数据,但我们将在应用本身中演示如何使用Android SDK向Firestore写入数据。
我们应用中的主要模型对象是餐厅(参考model/Restaurant.java)。Firestore数据分为文档、集合和子集合。我们将每个餐厅存储为顶级集合“restaurants”中的一个文档。要了解更多关于Firestore数据模型的信息,请阅读关于文档和集合的内容。 1. 首先,让我们获取一个FirebaseFirestore的实例来进行操作。编辑MainActivity中的initFirestore()方法: private void initFirestore() { mFirestore = FirebaseFirestore.getInstance(); 2. 在应用中添加功能,当我们点击溢出菜单中的“添加随机项目”按钮时,创建10个随机餐厅。填写onAddItemsClicked()方法: private void onAddItemsClicked() { // 获取到“restaurants”集合的引用 CollectionReference restaurants = mFirestore.collection(“restaurants”); for (int i = 0; i < 10; i++) { // 获取一个随机的Restaurant POJO Restaurant restaurant = RestaurantUtil.getRandom(this); // 向“restaurants”集合添加一个新文档 restaurants.add(restaurant); 关于上面的代码,有几个重要的注意事项: • 我们首先获取了“restaurants”集合的引用。集合在添加文档时会隐式创建,因此在写入数据之前不需要创建集合。 • 文档可以使用普通的Java对象(POJOs)创建,我们使用它来创建每个Restaurant文档。 • add()方法向集合中添加一个文档,并自动生成一个ID,因此我们不需要为每个Restaurant指定一个唯一的ID。 3. 现在再次运行应用,并点击溢出菜单中的“添加随机项目”按钮来调用您刚刚编写的代码: 退出登录 添加随机项目 如果您导航到Firebase控制台 -> “Firestore数据库 -> “数据”选项卡,您应该看到新添加的数据如下。恭喜,您刚刚向Cloud Firestore写入了数据!在下一步中,我们将学习如何在应用中显示这些数据。
计算机科学学院
第3页,共13页
COMP5216移动计算
LabW04
restaurants>7Ay32c3kQ7Vo… friendly – eats – 8845b restaurants 7Ay32c3kQ7VodozVqpDC 1 开始收集 添加文档 开始收集 restaurants 7Ay32c3kQ7VodozVapDC 添加字段 FKEi5VyHFSSK7TDOHN11 Cz2eE2NXhrntUvEYOXBz avgRating:3.072849915035425 category:“Indian I2e5AbgvgCW7wV8Bjx8S K8TY6Php03epGn6bgP1m KULBcBPKEOv1KtOr6zz3 city:”Indianapolis name:“Fire Eatery” numRatings:13 Z0gf6e0CwBcAgu855KGK photo:https://storage.googleapis.com/firestorequickstart juaMWaDPWJzIxnmaX1of price:3 t9Y61uDfIGGhzKXYLXjz zJt16mY2F83v2upnRU3
任务3:从Cloud Firestore显示数据 在这个任务中,我们将学习如何从Cloud Firestore检索数据并在我们的应用中显示它。 1. 从Cloud Firestore读取数据的第一步是创建一个查询。修改initFirestore()方法: private void initFirestore() { mFirestore = FirebaseFirestore.getInstance(); mQuery = mFirestore.collection(“restaurants”) // 获取50个评分最高的餐厅 .orderBy(“avgRating”, Query.Direction.DESCENDING .limit(LIMIT); 2. 现在我们想要监听这个查询,以便我们获取所有匹配的文档,并实时收到未来更新的通知。因为我们的最终目标是将此数据绑定到RecyclerView,我们需要创建一个RecyclerView.Adapter类来监听数据。虽然这将展示Cloud Firestore的实时功能,但也可以简单地获取数据而无需监听。您可以在任何查询或引用上调用get()来获取数据快照。 打开FirestoreAdapter类,它已经部分实现。首先,让我们使适配器实现EventListener并定义onEvent函数,以便它可以接收Firestore查询的更新:
计算机科学学院
第4页,共13页
COMP5216移动计算
LabW04
public abstract class FirestoreAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter
计算机科学学院
Y1 Friendly Eats
AIR
第5页,共13页
COMP5216移动计算
LabW04
任务4:在Cloud Firestore中对数据进行排序和过滤 该应用目前显示整个集合中评分最高的餐厅,但在实际的餐厅应用中,用户希望对数据进行排序和过滤。例如,应用应该能够显示“纽约最受欢迎的海鲜餐厅”或“最便宜的披萨”。
点击应用顶部的白色栏会弹出一个过滤器对话框。在本节中,我们将使用Firestore查询来使这个对话框工作: Y1Friendly Eats 过滤 所有食物 任何价格 按评分排序 应用 1. 编辑MainActivity.java中的onFilter()方法。这个方法接受一个Filters对象,这是我们创建的一个辅助对象,用于捕获过滤器对话框的输出。我们将更改这个方法,从过滤器构建一个查询。 在下面的代码片段中,我们通过附加where和orderBy子句来构建一个Query对象,以匹配给定的过滤器。
计算机科学学院
第6页,共13页
COMP5216移动计算
LabW04
@Override public void onFilter(Filters filters) { // 构建查询基本查询 Query query = mFirestore.collection(“restaurants”); if (filters.hasCategory()) { // 类别(等式过滤器) query = query.whereEqualTo(“category”, filters.getCategory()); if // 城市(等式过滤器) (filters.hasCity()) { query = query.whereEqualTo(“city”, filters.getCity()); // 价格(等式过滤器) if (filters.hasPrice()) { query = query.whereEqualTo(“price”, filters.getPrice()); // 按(orderBy和方向)排序 if (filters.hasSortBy()) { query = query.orderBy(filters.getSortBy(), filters.getSortDirection()); // 限制项目 query = query.limit(LIMIT); mQuery = query; mAdapter.setQuery(query); // 更新查询 // 设置标题 mCurrentSearchView.setText(Html.fromHtml(filters.getSearchDescription(this))); mCurrentSortByView.setText(filters.getOrderDescription(this)); mViewModel.setFilters(filters); // 保存过滤器 2. 运行应用并选择以下过滤器以显示最受欢迎的低价餐厅: 过滤 所有食物 任何地方 按受欢迎程度排序 取消 应用 3. 如果您使用adb logcat或Android Studio中的Logcat面板查看应用日志,您会注意到以下警告:
计算机科学学院
第7页,共13页
COMP5216移动计算
LabW04
W/Firestore Adapter: onEvent:error com.google.firebase.firestore.FirebaseFirestoreException: FAILED_PRECONDITION