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

Posted

技术标签:

【中文标题】在 Firebase 中管理聊天频道的最佳方式【英文标题】:Best way to manage Chat channels in Firebase 【发布时间】:2016-02-06 01:07:31 【问题描述】:

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

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

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

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

谢谢!

【问题讨论】:

不要合并 USERID1USERID2,如果 google 更改新用户的 uid 长度会发生什么?他们没有承诺尺寸 【参考方案1】:

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

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

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);
&lt;script src="https://getfirebug.com/firebug-lite-debug.js"&gt;&lt;/script&gt;

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

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

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

【讨论】:

我知道这是旧的,但只是在寻找一些想法。您可以通过将用户放在一个数组中并对其进行排序来使其变得灵活。然后,只是为了方便使用并防止其他人轻易猜到房间名称,只需将其制作为 MD5,或以某种方式对其进行哈希处理。通过这种方式,您可以扩大房间中的用户数量。我已经使用了一段时间了,它非常好。 谢谢你的积分。使用 js-sha256 模块散列对我有用。 '让 chatHash = SHA256('agent:' + agentId + '_user:' + userId)' 这是一个很好的答案,谢谢。但我想知道如何确保这个聊天室名称是唯一的。特别是对于更常见的名称。即使我将聊天存储在两个用户节点中,我也可以与 2 个 Franks 聊天。现在我正在考虑只使用 FB 键进行聊天,在每个用户的 /conversations 中存储一个引用,其中有 withUser: recipientUid 然后当其中一个用户发起聊天时,只需检查以确保一个还没有与其他用户存在。似乎这可能不是最好的设计。有什么想法吗?谢谢! 如果您还想为每个 userChatRoom 保留未读计数(在每个用户的上下文中),您会在每个聊天室对象中保留 lastRead 和 lastUpdated 时间戳吗? @Frank van Puffelen 如果有人离开小组怎么办?更改房间名称?如果是这样,其他人将失去以前对话的链接。通过将房间推送到房间的集合并将生成的ID添加到所有成员来生成房间ID有什么危害?【参考方案2】:

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

散列/MD5 策略当然是另一种方法,但您还必须将“路由”信息以及 $key 存储在同一节点上 - 这是重复 IMO(除非我遗漏了什么)。

【讨论】:

我认为他们这样做是为了保存用户发起聊天的信息。 那是真的,虽然要创建你对用户名进行排序的哈希,所以最后你真的不知道是谁启动了那个频道。如果你真的需要这些信息,你可以在你的聊天频道节点下创建属性。通常,如果频道有多个用户,您应该让某个人成为该频道的“管理员”,并赋予一些特殊的“权力”,但这取决于您的应用程序的需求。【参考方案3】:

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

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

【讨论】:

【参考方案4】:

在 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)

【讨论】:

你能提供更多关于你是如何做到这一点的信息吗?我一直在尝试不同的事情,但我无法理解它。 这里的重点是创建一个带有 ids 的发送者和接收者字符串。因此,在我的示例中,我们创建了一个字符串:“agent:142_user:5346”,这意味着代理 id 为 142,用户 id 为 5346。您也可以在字符串中使用两个用户,例如“user:123_user:312”。然后为了使其难以阅读,我们使用哈希算法。它会转换类似“e769925f0d2068d6280e3a61b6”的东西。我在这里使用 SHA256,但您可以使用不同的算法,例如 MD5 等。 这将生成长度为 64 的字符串。如果所有聊天室都维护一个参与者数组以便我们可以轻松查询是否存在任意数量的用户进行过聊天的聊天,这不是很好吗?在一般情况下,它也可以适合任何数量的用户。在这个散列用例中,您必须记住放置字符串的模式,如果您与 100 多个用户进行群聊,它也不会很好。那么你会循环,肯定会让代码更复杂??

以上是关于在 Firebase 中管理聊天频道的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

在多频道聊天应用程序中,如何显示仅与特定聊天频道相关的消息?

在 PostgreSQL 中存储一对多或多对多关系的最佳方式是啥?

在网站上动态嵌入 youtube 频道的最佳方式是啥(首选 wordpress)

PubNub 最佳实践:如何管理私人房间?

如何为 ChatApp 制作 ListView 来管理所有聊天?

Unity 聊天应用程序