实时通讯移动应用程序的 Firebase 安全规则

Dim*_*tri 6 firebase firebase-security firebase-authentication firebase-realtime-database

我正在使用 Ionic/Angular 和 Firebase 构建实时消息传递工具。我使用 Firebase 身份验证来验证我的用户身份,并使用 Firebase DB 来存储消息和消息线程。

我的问题是,我应该使用什么安全规则才能使消息线程私有且可行,并且仅对参与给定消息线程的 2 个人来说是可写的。

我的数据库结构现在看起来像这样:

-chats
  --Message_thread_ID
    ---Unique_ID_generated_message by Firebase
       ----Message
       ----Sender ID
       ----Receiver ID
    ---Unique_ID_generated_message by Firebase
       ----Message
       ----Sender ID
       ----Receiver ID
  --Message_thread_ID
    ---Unique_ID_generated_message by Firebase
       ----Message
       ----Sender ID
       ----Receiver ID
Run Code Online (Sandbox Code Playgroud)

我当前的 firebase 安全规则是:

{
  "rules": {
    ".read": "auth != null",
    ".write": false,
    "$messageThreadID": {
        ".write": "auth != null && !data.exists()",
        ".read": "auth != null"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但这样任何经过身份验证的用户都将能够读取任何用户之间的所有消息。这不是我想要的。我想让消息线程仅对任何给定线程中的两个用户保持私有。

我应该如何重组我的数据库以获得最佳解决方案?

PS:我有办法使用后端来做到这一点,或者为各自线程的两个用户中的每一个制作两个副本,但这些解决方案看起来确实很次等。

Fra*_*len 4

您当前的数据模型仅存储聊天消息本身。它还不存储每个聊天的参与者。或者好吧......它确实将其存储在消息本身中,但这对于您的安全规则来说还不够明确,无法读取它。

因此,第一步是将有关谁是哪个成员的数据添加到您的模型中:

members
  Message_thread_ID1
    member_uid_1: true
    member_uid_2: true
  Message_thread_ID2
    member_uid_1: true
    member_uid_3: true
Run Code Online (Sandbox Code Playgroud)

现在我们拥有更新安全规则所需的所有信息。

{
  "rules": {
    ".read": "auth != null",
    ".write": false,
    "$messageThreadID": {
        ".write": "root.child('members').child($messageThreadID).child(auth.uid).exists()",
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,只有当用户是消息线程的成员时,才能写入该线程。

对于应用程序的各种用例,您通常会得到多个此类查找列表。例如,您可能希望在用户登录时显示用户的消息线程列表。为了有效地做到这一点,您可能会添加“每个用户的消息线程”列表,这几乎是上面列表的逆members

threads_per_user
  member_uid_1: true
    Message_thread_ID1
    Message_thread_ID2
  member_uid_2: true
    Message_thread_ID1
  member_uid_3: true
    Message_thread_ID2
Run Code Online (Sandbox Code Playgroud)

对于具有关系/SQL 背景的开发人员来说,这种数据结构最初感觉非常不自然,但实际上在 NoSQL 数据库中很常见。

了解更多: