Cloud Firestore子集合规则

Ger*_*its 3 firebase firebase-security google-cloud-firestore

我正在使用具有(哇!)聊天功能的iOS应用。整个应用程序大量使用Firebase工具,对于数据库,我正在使用新的Cloud Firestore解决方案。

目前,我正在使用数据库规则加强安全性,但是我在自己的数据模型上苦苦挣扎:)这可能意味着我的数据模型选择不佳,但是我对此非常满意,除了执行规则部分。

该模型的对话部分如下所示。在数据库的根目录下,有一个conversations集合:

/conversations/$conversationId
        - owner // id of the user that created the conversation
        - ts // timestamp when the conversation was created
        - members: {
                $user_id_1: true // usually the same as 'owner'
                $user_id_2: true // the other person in this conversation
                ...
          }
        - memberInfo: {
                // some extra info about user typing, names, last message etc.
                ...
          }
Run Code Online (Sandbox Code Playgroud)

然后,我在每个对话中都有一个子集合,称为消息。消息文档非常简单,仅包含有关每个已发送消息的信息。

/conversations/$conversationId/messages/$messageId
        - body
        - sender
        - ts
Run Code Online (Sandbox Code Playgroud)

和该模型的屏幕截图: 该模型

对话文档中的规则相当简单,易于实现:

match /conversations/{conversationId} {
  allow read, write: if resource.data.members[(request.auth.uid)] == true;

  match /messages/{messageId} {
        allow read, write: if get(/databases/$(database)/documents/conversations/$(conversationId)).data.members[(request.auth.uid)] == true;
  }
}
Run Code Online (Sandbox Code Playgroud)

问题

我的问题是该对话中的消息子集合。上面的作品,但我不喜欢get()在那儿使用电话。每个get()通话都会执行读取操作,因此会在月底影响我的账单,请参阅文档

...

如果我正在构建的应用程序将成功,则文档读取的内容确实很少,这可能会成为问题,但是每次用户打开对话时执行此操作似乎效率低下。我真的很喜欢模型中的子集合解决方案,但是不确定如何在此处有效地实现规则。

我愿意接受任何数据模型更改,我的目标是评估没有这些get()调用的规则。任何想法都非常欢迎。

Tod*_*man 5

老实说,我认为您对自己的结构还可以,可以直接使用get。原因如下:

  1. 如果您要在子集合中获取一堆文档,则Cloud Firestore通常足够聪明,可以根据需要缓存值。例如,如果您要获取“ conversions / chat_abc / messages”中的所有200个项目,则Cloud Firestore将仅执行一次该get操作,然后将其重新用于整个批处理操作。因此,您将获得201次读取,而不是400次读取。

  2. 通常,我不喜欢优化安全规则中的定价。是的,您最终可能会为每个操作多读一两次,但这可能不会以相同的方式给您带来麻烦,例如,编写的Cloud Function可能写得不好。这些是您最好进行优化的地方。