【发布时间】:2019-01-31 07:24:02
【问题描述】:
我正在使用 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])
然后检查这些查询是否返回对话。如果是这样,我使用该对话添加一条消息,否则我创建一个新对话。
它可以工作,但它是一堆代码,效率很低。
所以我的问题是:
- 有没有更好的方法来做到这一点?
- 如何使用“array-contains”检查多个项目?
- 我有一个 participantsArray 和一个 participants 字段,因为我不知道如何对对象数组执行“数组包含”。有没有办法或者我应该保留这两个字段?
PS: 之前,我曾经像这样查询参与者对象中的对象:
db.collection("conversations").where(`participants.${userId}.id`, "==", userId)
这是在“array-contains”存在之前进行查询的建议方法 - 但是当与 orderBy 结合使用时,我必须为每个用户创建一个索引,这不是一个真正的选择。
【问题讨论】:
标签: javascript firebase google-cloud-firestore