对于以下应用程序,什么是好的 firestore 数据结构?

What would be a good firestore data structure for the following app?

我想实现以下约束:

我有用户使用 firebase 身份验证登录,从而获得用户 uid。我想在 firestore 服务器端尽可能地使用 firestore 规则,在写这个问题时我不知道的任何其他技术上做大部分 constraints/checks。

我想到了以下结构:

movies: {
  userUid1: {
    movie1:{
      name: "dummy name 1"
    },
    movie2:{
      name: "dummy name 2"
    }
  },
  userUid2: {
    movie1:{
      name: "first dummy name"
    },
    movie2:{
      name: "second dummy name"
    },
    movie3:{
      name: "third dummy name"
    }
  }
}

或:

movies: {
  movieUid1: {
    name: "dummy name 1",
    userId: "userUid1"
  },
  movieUid2: {
    name: "dummy name 2",
    userId: "userUid1"
  },
  movieUid3: {
    name: "dummy name 3",
    userId: "userUid2"
  },
  movieUid4: {
    name: "dummy name 4",
    userId: "userUid2"
  },
  movieUid5: {
    name: "dummy name 5",
    userId: "userUid2"
  }
}

这个项目只适合一些朋友,所以没什么大不了的,但我仍然想尽可能地构建最好的方式。 我认为这无关紧要,但我使用 flutter 来创建应用程序。

一般来说,我认为典型的做法是两者兼顾。 Firestore 在诸如“显示电影 collection 中用户 ID xyz 的所有电影”或“找到隐藏在某个我不认识的用户下的电影记录 xyz”这样的查询上表现不佳。

所以通常情况下,如果您需要查找特定电影,以及获取一个用户的所有电影列表,您将以两种方式存储数据,然后使用触发器(在本例中为 Firebase 函数)使它们保持同步。

这个post(What is denormalization in Firebase Cloud Firestore?)的答案有很好的解释。

如果您需要跟踪用户保存的电影数量(或稍后存储任何用户相关信息),您可以尝试以下结构:

users -> { userId } -> movies -> { movieId }
(col)      (doc)       (col)       (doc)

任何与用户相关的用户信息都可以存储在用户的文档和他们的电影中 sub-collection。


Users can save movies (titles) and view the title uploaded by other users too.

然后您可以使用 Collection Group 查询来列出所有电影。


All users must be able to access all of the movies, but must only be able to edit/add/delete their own.

您可以为此使用安全规则。这些规则应该有效:

match /users/{userId}/movies/{movieId} {
  // Only authenticated users can read
  allow read: if request.auth != null;

  // Only the user who added movie can write/delete
  allow write: if request.auth != null && request.auth.uid == resource.data.author;
}

您需要将用户的 UID 存储在电影文档中才能使上述规则生效。您可以使用 get() 从用户文档中读取数据。


User can have up to 3 movies added

您可以添加一个规则,从用户的文档中读取用户添加的电影数量,如果该值为 3,则拒绝创建。


您可以查看此答案以阅读有关根级别集合和 sub-collections:

的更多信息