在 Firebase 中管理聊天频道的最佳方式

Best way to manage Chat channels in Firebase

在我的主页上,我有一个用户列表,我想选择并打开一个频道与其中之一聊天。

我在想如果使用 id 是最好的方法并控制对 USERID1-USERID2 之类的频道的访问。

当然,用户2也可以打开同一个频道,所以我想找一个更容易控制的东西。

如果你想帮助我,请在 javascript 中使用 firebase url/array 给我一个例子 url/array。

谢谢!

处理此类 1:1 聊天室的常用方法是根据用户 ID 生成房间 URL。正如您已经提到的,这样做的一个问题是任何一个用户都可以发起聊天,并且在这两种情况下他们最终应该在同一个房间。

您可以通过在复合键中按字典顺序对用户 ID 进行排序来解决此问题。例如使用用户名,而不是 ids:

var user1 = "Frank"; // UID of user 1
var user2 = "Eusthace"; // UID of user 2

var roomName = 'chat_'+(user1<user2 ? user1+'_'+user2 : user2+'_'+user1);

console.log(user1+', '+user2+' => '+ roomName);
            
user1 = "Eusthace";
user2 = "Frank";

var roomName = 'chat_'+(user1<user2 ? user1+'_'+user2 : user2+'_'+user1);

console.log(user1+', '+user2+' => '+ roomName);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

一个常见的后续问题似乎是如何为当前用户显示聊天室列表。上面的代码没有解决这个问题。正如在 NoSQL 数据库中常见的那样,您需要扩充数据模型以支持此用例。如果你想为当前用户显示聊天室列表,你应该为你的数据建模以允许这样做。最简单的方法是将每个用户的聊天室列表添加到数据模型中:

"userChatrooms" : {
  "Frank" : {
    "Eusthace_Frank": true
  },
  "Eusthace" : {
    "Eusthace_Frank": true
  }
}

如果您担心密钥的长度,可以考虑使用组合 UID 的哈希码而不是完整的 UID。


上面的最后一个 JSON 结构也有助于保护对房间的访问,因为您可以编写安全规则以仅允许在其 userChatrooms 节点下列出房间的用户访问:

{
  "rules": {
    "chatrooms": {
      "$chatroomid": {
        ".read": "
           root.child('userChatrooms').child(auth.uid).child(chatroomid).exists()
        "
      }
    }
  }
}

在 Frank van Puffelen 和 Eduard 的指导下,使用 js-sha256 模块进行哈希对我有用。

import SHA256 from 'crypto-js/sha256'
let agentId = 312
let userId = 567
let chatHash = SHA256('agent:' + agentId + '_user:' + userId)

在典型的数据库架构中,每个 Channel / ChatGroup 都有自己的节点和唯一的 $key(由 Firebase 创建)。哪个用户先打开频道并不重要,但是一旦创建了节点(和相应的 $key),您就可以将其用作频道 ID。

散列/MD5 策略当然是另一种方法,但是你还必须在同一节点上存储 "route" 信息和 $key - 这是重复的 IMO(除非我遗漏了一些东西).

我们决定对用户的 uid 进行哈希处理,这意味着如果您知道其他人的 uid,您可以查找任何现有对话。

每个对话还存储一个用于其安全规则的 uid 列表,因此即使您可以猜出哈希值,您也会受到保护。