我正在使用Firestore和Javascript(vue.js)构建一对一的聊天应用程序。
我有一个对话和一个消息文档,定义如下:
.collection(“ coversation”)。doc()
conversation: {
participantsArray: ["id1", "id2"],
participants: {
id1: {
/* details like avatar & name */
},
id2: {
/* details like avatar & name */
}
}
}
.collection(“ coversation”)。doc(“ foo”)。collection(“ messages”)。doc()
message: {
message: "foo"
}
这很棒,所以我现在可以像这样查询特定用户的所有对话:
db.collection('conversations').where("participantsArray", "array-contains", userId)
我现在遇到的问题如下:
我想查询特定的对话,例如:
db.collection('conversations')
.where("participantsArray", "array-contains", userId)
.where("participantsArray", "array-contains", chatpartnerId)
但是这是行不通的,因为不允许使用双重“数组包含”并引发错误消息。
目前对我有用的是像这样打两个电话:
db.collection('conversations')
.where(`participantsArray`, '==', [userId, chatpartnerId])
db.collection('conversations')
.where(`participantsArray`, '==', [chatpartnerId, userId])
,然后检查这些查询中的任何一个是否返回对话。如果是这样,我将使用该对话添加一条消息,否则,我将创建一个新对话。
它可以工作,但这是一堆代码,效率很低。
所以我的问题是:
PS: 以前,我曾经像这样查询参与者对象中的对象:
db.collection("conversations").where(`participants.${userId}.id`, "==", userId)
这是在“数组包含”存在之前提出的查询方法-但是当与orderBy结合使用时,我必须为每个用户创建一个索引,这并不是一个选择。
答案 0 :(得分:3)
我找到了一种方法来查询单个对话。
由于我既有(1)个参与者的详细信息在“ 参与者”对象中,又有(2)参与者ID在“ participantsArray ”中,所以我可以查询进行如下单个对话:
db.collection('conversations')
.where(`participants.${userId}.id`, "==", userId)
.where(`participants.${chatPartnerId}.id`, "==", chatPartnerId)
所以我现在很高兴。但是,这三个问题仍然存在,因此,如果有人可以正确回答这些问题,他们的回答将非常有价值:)
答案 1 :(得分:0)
另一种选择是在文档中有两个字段,一个字段用于按字母顺序排列的最低用户ID(LAUID),另一个用于按字母顺序排列的最高用户ID(HAUID)。如果您在客户端上同时拥有两个用户ID,但不知道哪个是哪个ID,则可以找出两个ID中的哪个ID较大(UID2),哪个ID最小(UID1),那么您的查询将是HAUID等于UID2,其中LAUID等于UID1