firebase - 如何在 Firestore 和 Android 中选择位置?

标签 firebase database-design google-cloud-firestore

我对 Cloud Firestore 非常陌生,所以请帮助我。我正在为青少年创建一个应用程序,我想在其中显示每个城市非常好的地点的列表。我还希望每个用户都可以将任何位置保存到最喜欢的部分,以便他或她可以向他或她的 friend 显示该位置列表。

My actual data:

  • db -> users(所有用户)
  • 数据库 -> 位置(所有位置)

My problem:

我想找到一种方法将用户的位置设置为收藏夹。我正在考虑在每个用户下创建一个新部分来保存每个最喜欢的位置,例如:

  • 数据库 -> 用户(所有用户) -> 收藏夹

My question:

如何在一个用户和喜爱的位置之间建立联系?我认为这是一种一对多的关系。执行此操作的最佳解决方案是什么?

任何想法或代码将不胜感激!

最佳答案

What is the best solution to do this?

我知道每个人都在寻找最佳解决方案,但在 NoSQL 数据库领域,没有最佳解决方案。您可以通过多种方式为像您这样的应用程序建立数据库模型并获得相同的结果,我将向您展示原因。在此之前,请先看一下我这个 post的回答。 ,更好地理解 NoSQL 数据库的“完美”、“最佳”或“正确”解决方案的概念。

最好的解决方案是,开个玩笑:) 实现您正在寻找的这个最喜欢的功能列表的推荐方法是使用数组。您的数据库架构可能如下所示:

Firestore-root
   |
   --- users (Collection)
   |     |
   |     --- uid (document)
   |           |
   |           --- favoriteLocations: ["favoriteLocationId", "favoriteLocationId"]
   |
   --- locations (Collection)
         |
         --- locationId (document)
               |
               --- //Location details

如您所见,favoriteLocations 数组仅包含位置 ID。因此,为了获取位置详细信息,您应该获取这些 ID 并进行额外的数据库 get() 调用。

另一种方法是不存储位置 ID 数组,而是存储 map 数组或位置对象数组。如果您有一定数量的喜爱位置,例如 5 个、10 个甚至 50 个,但不是 500 个,则此选项效果很好。如果您需要存储 500 个位置,您的原因是什么将某个位置存储为收藏夹?

在这种情况下要记住的重要一点是,文档有限制。因此,当您可以在文档中放入多少数据时,存在一些限制。根据官方文档关于usage and limits :

Maximum size for a document: 1 MiB (1,048,576 bytes)

如您所见,单个文档中的数据总量限制为 1 MiB。当我们谈论存储文本时,您可以存储相当多的内容,但随着数组变得越来越大,请小心此限制。

如果您想存储单个文档允许存储的更多数据,那么您应该使用集合。通过这种方式,您可以在每个用户对象下创建一个子集合,该子集合将作为文档、位置对象保存。你的数据库结构应该像这样:

Firestore-root
   |
   --- users (Collection)
   |     |
   |     --- uid (document)
   |           |
   |           --- favoriteLocations (Collection)
   |                |
   |                --- favoriteLocationId (document)
   |                       |
   |                       --- //Location details
   |
   --- locations (Collection)
         |
         --- locationId (document)
               |
               --- //Location details

要查询如下所示的数据库,请使用以下代码行:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference favoriteLocationsRef = rootRef.collection("users").document(uid).collection(favoriteLocations);
favoriteLocationsRef.get(/* ... */);

另一种方法是对数据进行去名词化并创建您的 favoriteLocations 子集合,作为顶级集合,如下所示:

Firestore-root
   |
   --- users (Collection)
   |     |
   |     --- uid (document)
   |           |
   |           --- //User details
   |
   --- locations (Collection)
   |     |
   |     --- locationId (document)
   |           |
   |           --- //Location details
   |
   --- favoriteLocations (Collection)
         |
         --- uid (document)
              |
              --- userFavoriteLocations (collection)
                    |
                    --- favoriteLocationId (document)
                           |
                           --- //Location details

相应的查询应如下所示:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference favoriteLocationsRef = rootRef.collection("favoriteLocations").document(uid).collection(userFavoriteLocations);
favoriteLocationsRef.get(/* ... */);

或者更简单的方法,如下所示:

Firestore-root
   |
   --- users (Collection)
   |     |
   |     --- uid (document)
   |           |
   |           --- //User details
   |
   --- locations (Collection)
   |     |
   |     --- locationId (document)
   |           |
   |           --- //Location details
   |
   --- favoriteLocations (Collection)
         |
         --- locationId (document)
               |
               --- uid: "uid"
               |
               --- //Other location details

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query query = rootRef.collection("favoriteLocations").whereEqualTo("uid", uid);
favoriteLocationsRef.get(/* ... */);

如您所见,我已将用户的 uid 添加为位置对象的属性,以便您可以轻松获取特定用户拥有的所有最喜欢的位置。

您可以选择最适合您的应用用例的解决方案“最佳”:)

P.S.也请看看我的回答 post ,我在其中详细解释了 Firestore 中的集合映射数组

关于firebase - 如何在 Firestore 和 Android 中选择位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53099589/

相关文章:

java - Google 登录身份验证不起作用

javascript - 在没有 Firebase 的情况下使用 Webhook

javascript - 如何正确从 observable 获取数组数据?

flutter - 每个应用启动时Flutter Stream只能运行一次

javascript - Firebase child() 与 Angularfire $firebaseObject

firebase - 为聊天应用程序构建 NoSQL 数据库(使用 FireBase)

mysql - 单个FK指来自多个表的PK

sql - 如何在 MySQL 中表示树及其内容?

sql - 顺序扫描以 varchar_pattern_ops 索引的列

go - 如何获取Firestore文档的ID?