根据用户的 uid 生成 Firestore 文档的文档 ID

2024-03-14

在我的聊天应用程序中,我在两个用户之间进行私人聊天。我打算使用这两个用户的 docId/uid 设置聊天文档的 id,使其不依赖于它们组合的顺序,并且我可以使用用户的 uid 确定聊天文档的 docId,而不管其顺序如何uid。

我知道,我也可以使用 where 子句来获取聊天文档。我生成聊天文档的 docId 的方法有什么重大缺陷吗?我应该让它自动生成并使用 firestore 和 limit(1) 支持的普通 where 子句来获取聊天吗?

基本上,看来我正在寻找的是加密uid1以这样的方式,它只返回一个数字,然后与uid2然后将它们添加在一起以创建 ChatId。这样,它就不会依赖于我添加它们的顺序,并且我可以获得 chatId,并可能使用 Base64 编码将该数字转换回字符串。这样,如果我知道参与聊天的用户,我可以生成相同的 ChatId。这会起作用还是有任何缺陷?


将每个用户 ID 转换为数字然后将它们相加可能会导致冲突。举一个简单的例子,考虑一下可以将数字 5 相加的多种方法:0+5, 1+4, 2+3.

这个答案建立在@NimnaPerera 的 https://stackoverflow.com/users/10406995/nimna-perera answer https://stackoverflow.com/a/66834590/3068190.

方法一:<uid>_<uid>

如果您的应用程序不打算使用大型组,您可以使用<uid>_<uid>格式。为了确保两个用户 ID 以相同的方式排序,您可以先对它们进行排序,然后使用某些分隔符将它们组合在一起。

实现此目的的一个简短方法是使用:

const docId = [uid1, uid2].sort().join("_");

如果你想进行三方群聊,只需在数组中添加新的 userID 即可:

const docId = [uid1, uid2, uid3].sort().join("_");

您还可以将其变成一种可读性方法:

function getChatIdForMembers(userIds) {
  return userIds.sort().join("_");
}

这是一个实际的例子:

const uid1 = "apple";
const uid2 = "banana";
const uid3 = "carrot";

[uid1, uid2].sort().join("_"); // returns "apple_banana"
[uid1, uid3].sort().join("_"); // returns "apple_carrot"
[uid2, uid1].sort().join("_"); // returns "apple_banana"
[uid2, uid3].sort().join("_"); // returns "banana_carrot"
[uid3, uid1].sort().join("_"); // returns "apple_carrot"
[uid3, uid2].sort().join("_"); // returns "banana_carrot"

// chats to yourself are permitted
[uid1, uid1].sort().join("_"); // returns "apple_apple"
[uid2, uid2].sort().join("_"); // returns "banana_banana"
[uid3, uid3].sort().join("_"); // returns "carrot_carrot"

// three way chat
[uid1, uid2, uid3].sort().join("_"); // returns "apple_banana_carrot"
[uid1, uid3, uid2].sort().join("_"); // returns "apple_banana_carrot"
[uid2, uid1, uid3].sort().join("_"); // returns "apple_banana_carrot"
[uid2, uid3, uid1].sort().join("_"); // returns "apple_banana_carrot"
[uid3, uid1, uid2].sort().join("_"); // returns "apple_banana_carrot"
[uid3, uid2, uid1].sort().join("_"); // returns "apple_banana_carrot"

方法2:成员列表属性

如果您打算支持群聊,则应使用自动文档 ID(请参阅CollectionReference#add() https://firebase.google.com/docs/reference/js/firebase.firestore.CollectionReference#add)并将聊天成员列表存储为其字段之一,如中介绍的@NimnaPerera 的 https://stackoverflow.com/users/10406995/nimna-perera answer https://stackoverflow.com/a/66834590/3068190为了更好地使用查询。

我推荐两个领域:

  • "members"- 包含每个聊天成员 ID 的数组。这允许您查询/chats包含给定用户的聊天的集合。
  • "membersAsString"- 一个字符串,通过排序构建"members"并使用加入他们"_"。这允许您查询/chats包含确切成员列表的聊天的集合。
"chats/{chatId}": {
  "members": string[], // list of users in this chat
  "membersAsString": string, // sorted list of users in this chat, delimited using "_"
  /* ... */
}

要查找我参与的所有聊天:

const myUserId = firebase.auth().currentUser.uid;

const myChatsQuery = firebase.firestore()
  .collection("chats")
  .where("members", "array-contains", myUserId);

myChatsQuery.onSnapshot(querySnapshot => {
  // do something with list of chat documents
});

要查找 Apple、Banana 和 I 之间的所有三向聊天:

const myUserId = firebase.auth().currentUser.uid;
const members = [myUserId, "banana", "apple"];
const membersAsString = members.sort().join("_");

const groupChatsQuery = firebase.firestore()
  .collection("chats")
  .where("membersAsString", "==", membersAsString);

groupChatsQuery.onSnapshot(querySnapshot => {
  // do something with list of chat documents
  // normally this would return 1 result, but you may get
  // more than one result if a user gets added/removed a chat
});

正常的流程是:

  1. 获取相关聊天列表
  2. 对于每次聊天,获取最新消息
  3. 根据最新消息,对 UI 中的聊天进行排序
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据用户的 uid 生成 Firestore 文档的文档 ID 的相关文章

  • Google 饼图未显示所有数据行

    我正在尝试绘制人口与国家名称的关系图 我发现 Google 可视化库仅渲染前几个 实际上数字似乎是随机的 具体取决于我使用的数据 有时添加 其他 条目 但它没有t 实际上具有其余条目的值 Example 1 With all countri
  • 如何在不改变的情况下将字符串转换为字节?

    我需要一个解决方案将字符串转换为字节数组而不需要像这样进行更改 Input String s Test Output String s Test byte b Test 当我使用 s getBytes 那么回复是 B 428b76b8 但我
  • 来自 DataURL 的 Blob?

    Using FileReader s readAsDataURL 我可以将任意数据转换为数据 URL 有没有办法将数据 URL 转换回Blob使用内置浏览器 API 的实例 用户 Matt 一年前提出了以下代码 如何在javascript中
  • JQuery 动画文本

    找到简单 简单的动画文本是非常困难的 喜欢这个网站上的 内爆 http codecanyon net item jquery text animation full screen preview 233445 http codecanyon
  • 从未定义解构时避免错误

    可以说我有这个代码 const x y point Babel 会将其变成 var point point x point x y point y 这很好 但是如果点未定义怎么办 现在我得到一个错误 Cannot read property
  • 在 JavaScript 中比较表单中的两个数字

    当我尝试比较不同的数字时 数字发生变化 但文本部分保持不变 这只发生在较大 较小的情况下 而不会发生在 NaN 或相等的情况下 这是我的代码 function check var a document getElementById a va
  • 用于在子字符串中用破折号替换空格的正则表达式。

    我一直在努力寻找一种方法 可以用字符串中的破折号替换空格 但只能替换字符串特定部分内的空格 Source ABC This is a sub string DEF 我对正则表达式的尝试 s g 如果我使用正则表达式来匹配空格并替换 我会得到
  • 光滑的轮播缓动示例

    我正在使用 Slick Carousel http kenwheeler github io slick http kenwheeler github io slick 但不知道如何合并不同的幻灯片切换 有人有例子可以分享吗 这是我目前拥有
  • JQuery DataTable 单元格从行单击

    我正在尝试在 jquery 数据表上实现一个函数 该函数返回单击行的第一列和第四列 我正在遵循这个示例 它允许我操作单击的行http datatables net examples api select single row html ht
  • 在Python中删除带有重音符号的字符串中的所有非字母字符

    我正在尝试使用 Python 3 7 从包含重音符号的字符串中删除所有非字母字符 空格除外 我尝试了以下方法 import re text 29 1981 4 2008 clean text re sub W d text print cl
  • Web SQL 数据库 + Javascript 循环

    我正在尝试解决这个问题 但我自己似乎无法解决 我正在使用 Web SQL DB 但无法让循环正常使用它 I use for var i 0 i lt numberofArticles 1 i db transaction function
  • 将 JavaScript 引擎嵌入到 .NET 中 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 只是想知道是否有人尝试过将任何 js 引擎嵌入并实际集成到 net 环境中 我可以找到并实际使用 经过L
  • Postman - 如何计算 JSON 响应中特定对象的出现次数

    我是 JSON 和 Postman 的新手 我相信我正在尝试做一些非常简单的事情 我创建了一个 GET 请求 它将获得如下所示的 JSON 响应 在下面的例子中我想得到count响应中所有 IsArchived 属性 这些属性的数量因响应而
  • RTCDataChannel发送方法不发送数据

    我的 RTCDataChannel 遇到一个奇怪的问题 我正在对 WebRTC 进行一些研究 并且已经可以进行 WebRTC 音频 视频聊天 现在我想使用 RTCDataChannel 添加文本聊天和文件共享 我已经像这样创建了 RTCDa
  • 使用Promise而不拒绝它会导致内存泄漏吗? [复制]

    这个问题在这里已经有答案了 代码如下 function test value return new Promise function fulfill reject try fulfill true catch e throw e 我担心的是
  • 使用 Lodash 的 TypeScript:_.map(["123", " 234 "], _.trim) 返回 boolean[]?

    我有一个字符串数组 它们已像这样分割 var searchValue 600 800 123 180 var groups searchValue split gt 600 800 123 180 因此项目周围可能存在空格 并且我想删除空格
  • 使用 jQuery Tablesorter 操作后如何恢复当前页面?

    我正在使用 tablesorter 但无法找到有关插件 tablesorter 寻呼机的任何文档 问题是我有一个显示一些数据的表 并且在每一行中都有一个删除链接 该链接附加了要删除的元素的唯一标识符 显然 是否可以保存我正在删除的页面 然后
  • 在 Google Apps 脚本中的文本前插入换行符

    我需要在 Google 文档中的某些文本之前插入一些换行符 尝试过这种方法但出现错误 var body DocumentApp getActiveDocument getBody var pattern WORD 1 var found b
  • FullCalendar 检查选择日是否有活动?

    我正在使用 Full Calendar js 插件 到目前为止一切顺利 但我想检查开始和结束之间的选择是否有事件 我只需要返回 true 或 false 基本上 如果日期选择中已经存在事件 我想阻止用户创建事件 var calendar c
  • 使用 Lodash 将对象键转换为具有键值数量的数组[重复]

    这个问题在这里已经有答案了 我有一个产品对象 products bread 1 milk 2 cheese 2 chicken 1 我想要一个包含产品名称的数组 如下所示 products bread milk milk cheese ch

随机推荐

  • Java获取某个目录下所有文件的程序

    我正在开发这个程序来获取目录中的所有文件 由于某种原因 我在第 16 行收到 NullPointerException 但我不知道为什么 因为这是一个似乎在课堂上与我们的老师一起工作的模板 谢谢 import java util impor
  • MySQL 无法从现有表中进行选择,因为它不存在?

    我不知道发生了什么事 我有一张桌子叫project share invite 几个小时前 在我们的生产环境中 我无法再针对该表发出 SELECT MySQL 声称该表不存在 尽管它显示在show tables 今天机器上发生的唯一值得注意的
  • 搜索包含指定文本的 div

    我想在我的网站上创建一个搜索功能 在其中搜索 div 并忽略不符合我搜索内容的 div div 列表如下所示 div class subjects div soccer div div dancing div div soap div di
  • 如何以不同的风格或不同的构建类型使用不同的 proguard 文件?

    我需要为测试库制作不同的风格 为什么 好吧 我希望项目得到完全保护 所以我想始终启用缩小功能 即使对于调试构建类型 在进行测试时 我使用项目中的不同类 所以我决定使用flavor来更改proguard文件 它看起来像这样 android b
  • 使用 ASP.Net MVC 进行分页和排序网格

    想要改进这篇文章吗 提供此问题的详细答案 包括引用和解释为什么你的答案是正确的 不够详细的答案可能会被编辑或删除 我是 MVC 新手 并且不了解如何在网格上进行分页和排序 我习惯于使用 asp Net GridView 控件以及指向业务层中
  • Oracle SQL 一次选择中的非唯一表别名

    有人知道为什么这适用于两个表别名 x 吗 Select x company name x employee name FROM company x JOIN employee x ON x company id 5 我知道 id 5 的 J
  • 什么是 crossdomain.xml 文件?

    其实我希望我知道从哪里开始 我在我的个人网站中嵌入了第三方 SWF 图像库控件 SWF 是 XML 驱动的 我按如下方式动态加载 XML 文件 var flashvars xmlPath http www example com xml a
  • 如果双 SIM 卡槽之一的 SIM 卡发生更改,如何检索该卡的信息?

    我知道我们可以使用 TelephonyManager 类检索单张 Sim 卡的信息 但如何检索多张SIM卡的信息呢 假设我的手机丢失了 有人更换了其中一个插槽中的 SIM 卡 我如何接收 IMEI 号码 电话号码等信息 我只在更换 Sim
  • 无法将 [] 索引应用于“Array”类型的表达式

    对于下面的代码 我收到 无法将 索引应用于 数组 类型的表达式 目的是创建一个计算器模板 然后调用这些方法来运行各种操作 标记为 HERE 的区域出现错误 请帮忙 我是 C 编码的新手 因此 感谢所有帮助 如果有人也能向我解释这个问题 我希
  • Python 中的最大重量/最小成本二分匹配代码

    我正在寻找二分图中最大权重 最小成本匹配的Python代码 我一直在 NetworkX 中使用一般情况最大权重匹配代码 但发现它对于我的需求来说太慢了 这可能是因为通用算法速度较慢 而且 NetworkX 解决方案完全用 Python 实现
  • 使用 Heroku 部署 Flask

    我正在尝试将 Flask 应用程序部署到 Heroku 但是在推送代码时出现错误 2013 06 23T11 23 59 264600 00 00 heroku web 1 Error R10 Boot timeout gt Web pro
  • 如何使用vibed将文件加载到本地文件系统?

    我需要将数据从网络浏览器发送到本地文件系统 为了发送数据 我使用 Vue JS成分 https github com james2doyle vue file upload component
  • 从嵌入式 ZIP 存档中读取文件

    我有一个嵌入到较大文件中的 ZIP 存档 我知道存档在较大文件中的起始偏移量及其长度 是否有任何 Java 库可以让我直接读取存档中包含的文件 我正在思考ZipFile getInputStream http docs oracle com
  • Oracle 约束具有三列,但只有一行可以等于某个值

    这听起来可能很简单 也可能很简单 我有 3 列 一列带有常量字符串 名称 一列 状态 带有两个选项 外键 另一列 room id 是另一个表的父键 如何确保只设置一行相同名称的 ON 值 不能有多个具有相同名称的 ON 值的行 但可以有多个
  • Sqoop Hive 退出,状态为 1

    当我执行时 sqoop import connect jdbc mysql localhost testdb table test hive table test hive import m 1 我收到以下错误消息 13 04 21 16
  • 从 url 中去除域名(字符串)

    我正在像这样访问样式表集合 var css document styleSheets 0 它返回例如 http www mydomain com css main css 问题 如何剥离域名才能获得 css main css 这个正则表达式
  • 这些类和子类静态块何时执行(对于枚举)?

    我正在尝试定义一个基类 SubStatus 为枚举 什么时候static下面调用的块 如果它们是类而不是枚举 我相信它们会在调用类构造函数之后被调用 但因为他们是Enums 这些不是更像吗static课程开始 那么静态块可能是在容器加载静态
  • 如何将List<>写入parcel中

    public class Category implements Parcelable private int mCategoryId private List
  • tweepy 中的过滤

    我是新来的tweepy并且遇到了问题 我想下载带有特殊主题标签的推文 但似乎 stream filter track word1 word2 word3 在推文中查找这些单词 而不是在推文的主题标签中 如何过滤主题标签 您实际上可以根据您的
  • 根据用户的 uid 生成 Firestore 文档的文档 ID

    在我的聊天应用程序中 我在两个用户之间进行私人聊天 我打算使用这两个用户的 docId uid 设置聊天文档的 id 使其不依赖于它们组合的顺序 并且我可以使用用户的 uid 确定聊天文档的 docId 而不管其顺序如何uid 我知道 我也