根据用户的uid生成Firestore文档的doc ID [英] Generate Firestore document's doc Id based on Users' uids
问题描述
在我的聊天应用程序中,两个用户之间进行了私人聊天.我打算使用这两个用户的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
});
正常流程是:
- 获取相关聊天列表
- 对于每次聊天,获取最新消息
- 根据最新消息,在用户界面中对聊天进行排序
这篇关于根据用户的uid生成Firestore文档的doc ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!