情况
- 我有一个提供以下功能的消息传递 Android 应用程序
- 向一个选定的收件人发送消息直接消息
- 创建所有使用该应用程序的用户都会收到的公告(作者除外)
- 每个用户都会在他的手机上看到他收到的消息列表
- 每条消息都是未读、已读或已删除
- 我使用 Parse.com 作为后端
当前实施
在安卓客户端
- 当有新消息时,
MessageRequest
创建该类的新 messageRequest - 如果消息应该是直接的,则 messageRequest 的类型为 0,否则为类型 1
- 如果消息是直接的,则在 messageRequest 对象中存储有接收者
- messageRequest 对象存储到 parse.com
在 parse.com 后端
在afterSave
MessageRequest 中,检查消息是直接的还是公开的,并基于此
Message
在直接消息的情况下 -创建并保存该类的一个新消息对象- 在公告的情况下 - 对于除作者之外的每个用户,都会创建一个新的消息对象并将其添加到消息列表中,然后保存该列表
在这两种情况下,内容、类型等数据都从 messageRequest 对象复制到新创建的消息对象中。
为每个用户创建单独消息的原因是每个用户都可以将其置于另一个状态(未读、已读、已删除)。
表示未读、已读、已删除状态的状态列为消息对象设置(按未读)。
问题
当我调用MessageRequestParseObject.saveAll
中的方法时afterSave
,我得到Execution timed out - Request timed out 错误
我认为原因是请求必须在云代码中完成的时间有一些限制。就我而言,我正在为 1 MessageRequest 创建 ca 100 Messages
这对我来说似乎并不多,但也许我错了。
源代码
var generateAnnouncement = function(messageRequest, recipients) {
var messageList = [];
for (var i = 0; i < recipients.length; i++) {
var msg = new Message();
msg.set("type", 1);
msg.set("author", messageRequest.get("author"));
msg.set("content", messageRequest.get("content"));
msg.set("recipient", recipients[i]);
msg.set("status", 0)
messageList.push(msg);
}
Parse.Object.saveAll(messageList).then(function(list) {
}, function(error) {
console.error(error.message);
});
}
Parse.Cloud.afterSave("MessageRequest", function(request) {
var mr = request.object;
var type = mr.get("type");
if (type == 0) {
generateDirectMessage(mr);
} else {
var query = new Parse.Query(Parse.User);
query.notEqualTo("objectId", mr.get("author").id);
query.find().then(function(allUsersExceptAuthor) {
generateAnnouncement(mr, allUsersExceptAuthor);
}, function(error) {
console.error(error.message);
});
}
});
你会建议如何解决这个问题?
额外的想法
- 如何解决这个问题我唯一的另一个想法是只有一个 Message 对象,以及两个名为例如viewedBy 和deletedFor 的列,其中将包含已经查看该消息或已为他们删除该消息的用户列表。
在这种情况下,我不太确定查询的性能
另外,我知道,你们中的许多人认为他为什么不使用表来拆分 MessageRequest(在这种情况下实际上可以称为 Message)和 User 之间的 M:N 关系?
- 我的回答是我有这个解决方案,但是在 Android 代码中更难使用它,更多的指针,更多的包含在查询等中。
- 此外,无论如何,我必须在 on parse.com 后端为每个用户创建相同数量的表示状态的对象,所以我认为执行超时的问题最终会是相同的
更新 - 代表用户“收件箱”的模型
在“收件箱”中,用户可以看到直接消息和公告。它们按时间顺序排列。
更新 #2 - 使用数组来识别谁查看了谁标记为已删除
- 我只有一个
Message
对象,通过类型确定它是直接的还是公共的 - 添加了两个数组列
viewedBy
- 包含已查看消息的用户deletedFor
- 包含将邮件标记为已删除的用户
然后我对当前登录用户未删除的所有消息的查询如下所示
//direct messages for me
ParseQuery<Message> queryDirect = ParseQuery.getQuery(Message.class);
queryDirect.whereEqualTo("type", 0);
queryDirect.whereEqualTo("recipient", ParseUser.getCurrentUser());
//public announcements
ParseQuery<Message> queryAnnouncements = ParseQuery.getQuery(Message.class);
queryAnnouncements.whereEqualTo("type", 1);
//I want both direct and public
List<ParseQuery<Message>> queries = new ArrayList<ParseQuery<Message>>();
queries.add(queryDirect);
queries.add(queryAnnouncements);
ParseQuery<Message> queryMessages = ParseQuery.or(queries);
//... but only those which I haven't deleted for myself
queryMessages.whereNotEqualTo("deletedFor", ParseUser.getCurrentUser());
//puting them in correct order
queryMessages.addDescendingOrder("createdAt");
//and attaching the author ParseUser object (to get e.g. his name or URL to photo)
queryMessages.include("author");
queryMessages.findInBackground(new FindCallback<Message>() {/*DO SOMETHING HERE*/});