根据用户的uid生成Firestore文档的doc ID [英] Generate Firestore document's doc Id based on Users' uids

查看:54
本文介绍了根据用户的uid生成Firestore文档的doc ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的聊天应用程序中,两个用户之间进行了私人聊天.我打算使用这两个用户的docId/uid来设置聊天文档的id,而不依赖于他们组合的顺序,并且我可以使用用户的uid来确定聊天文档的docId,而无需考虑其顺序uid.

In my chat app, I have private chat between the two users. I intend to set the chat document's id using these two user's docId/uid in such a way that it doesn't depend on the order they're combined and I can determine the chat document's docId using the uid of users irrespective of the order of uid.

我知道,我也可以使用where子句来获取聊天文档.我生成聊天文档的docId的方法是否存在重大缺陷?我应该让它自动生成并使用firestore和limit(1)支持的常规where子句来获取聊天吗?

I know, I can use where clauses to get the chat doc as well. Is there any major flaw with my approach of generating the chat document's docId? Should I let it be generated automatically and use normal where clauses supported by firestore and limit(1) to get the chat?

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

basically, it seems I'm looking for is to encrypt uid1 in such a way that it returns a number only and then same with uid2 and then add them together to create the ChatId. This way it'll not depend on the order I use to add them and I can get the chatId and maybe convert that number back to a string using Base64 encode. This way, if I know the users participating in the chat, I can generate the same ChatId. Will that work or is there any flaw to it?

推荐答案

将每个用户ID转换为数字,然后将它们加在一起可能会导致冲突.举一个简单的例子,想一想将数字加起来等于5的多种方法: 0 + 5 1 + 4 2 + 3 .

Converting each user ID to a number and then adding them together will likely lead to collisions. As a simple example, think of the many ways you can add up to the number 5: 0+5, 1+4, 2+3.

此答案基于 @NimnaPerera的 如果您的应用程序不打算使用大群用户,则可以使用< uid> __< uid> 格式.为了确保两个用户ID的排序方式相同,您可以先对它们进行排序,然后使用一些定界符将它们组合在一起.

If your app doesn't plan on using large groups, you can make use of the <uid>_<uid> format. To make sure the two user IDs are ordered in the same way, you can sort them first and then combine them together using some delimiter.

一种简单的方法是使用:

A short way to achieve this is to use:

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

如果要进行三方群组聊天,只需在数组中添加新的用户ID:

If you wanted to have a three-way group chat, you'd just add the new userID in the array:

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

您也可以将其转变为可读性的方法:

You could also turn this into a method for readability:

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() ),并将聊天成员列表存储为其字段之一,如答案,以便更好地使用查询.

Method 2: Member list properties

If you intend on supporting group chats, you should use automatic document IDs (see CollectionReference#add()) and store a list of chat members as one of it's fields as introduced in @NimnaPerera's answer for better use of queries.

我建议两个字段:

  • 成员" -包含每个聊天成员ID的数组.这样,您就可以查询/chats 集合以查找包含给定用户的聊天.
  • "membersAsString" -一个字符串,它是通过对"members" 进行排序并使用"_" 加入它们而构建的.这样,您就可以查询/chats 集合以获取包含确切成员列表的聊天.
  • "members" - an array containing each chat member's ID. This allows you to query the /chats collection for chats that contain the given user.
  • "membersAsString" - a string, built from sorting "members" and joining them using "_". This allows you to query the /chats collection for chats that contain the exact list of members.
"chats/{chatId}": {
  "members": string[], // list of users in this chat
  "membersAsString": string, // sorted list of users in this chat, delimited using "_"
  /* ... */
}

查找我所属的所有聊天记录

To find all chats that I am a part of:

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之间的所有三方聊天:

To find all three-way chats between Apple, Banana and 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. 根据最新消息,在用户界面中对聊天进行排序

这篇关于根据用户的uid生成Firestore文档的doc ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆