将每个用户 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
});
正常的流程是:
- 获取相关聊天列表
- 对于每次聊天,获取最新消息
- 根据最新消息,对 UI 中的聊天进行排序