我正在使用Firestore和Javascript(vue.js)构建一种一对一的聊天应用程序。
我已经定义了一个会话和消息文档,如下所示: .collection("conversation").doc()
我现在遇到的问题如下:
我想查询特定的对话,例如:
我已经定义了一个会话和消息文档,如下所示: .collection("conversation").doc()
conversation: {
participantsArray: ["id1", "id2"],
participants: {
id1: {
/* details like avatar & name */
},
id2: {
/* details like avatar & name */
}
}
}
.collection("coversation").doc("foo").collection("messages").doc()
可以翻译成:在“coversation”集合中的“foo”文档下的“messages”子集合中的文档。message: {
message: "foo"
}
太好了,现在我可以这样查询特定用户的所有对话:
db.collection('conversations').where("participantsArray", "array-contains", userId)
我现在遇到的问题如下:
我想查询特定的对话,例如:
我要查询特定的对话:
db.collection('conversations')
.where("participantsArray", "array-contains", userId)
.where("participantsArray", "array-contains", chatpartnerId)
但是这种方法行不通,因为不允许使用双重的“array-contains”,会导致错误信息。
目前对我有效的方法是进行两次调用,如下所示:
db.collection('conversations')
.where(`participantsArray`, '==', [userId, chatpartnerId])
db.collection('conversations')
.where(`participantsArray`, '==', [chatpartnerId, userId])
然后检查这些查询是否返回了一个对话。如果是,我就使用该对话添加一条消息;否则,我创建一个新的对话。
它能够正常工作,但代码量很大且效率低下。
因此我的问题是:
- 有更好的方法吗?
- 如何执行“array-contains”以检查多个项目?
- 我有一个 participantsArray 和一个 participants 字段,因为我没有找到如何在对象数组上执行“array-contains”。有办法吗?还是应该保留这两个字段?
PS: 之前,我像这样在参与者对象中查询对象:
db.collection("conversations").where(`participants.${userId}.id`, "==", userId)
"array-contains"出现之前,这是查询的建议方式 - 但是当与orderBy结合使用时,我必须为每个用户创建一个索引,这不是一个真正的选择。