由于Firebase安全规则不能用于过滤子项,因此在基本多用户应用程序中构建数据以实现高效查询的最佳方法是什么?我已经阅读了几个指南,但是当他们按照给出的示例进行缩放时,它们似乎会崩溃。
假设你有像WhatsApp这样的基本消息应用程序。用户可以与其他用户组打开聊天,以在他们之间发送私人消息。以下是我在Firebase中如何组织这一点的初步想法(有点类似于文档中的this example):
{
users: {
$uid: {
name: string,
chats: {
$chat_uid : true,
$chat2_uid: true
}
}
},
chats: {
$uid: {
messages: {
message1: 'first message',
message2: 'another message'
}
}
}
}
可以将Firebase权限设置为仅允许用户在其用户对象中读取标记为chats
的{{1}}(并限制任意添加到true
对象等)。
然而,这种布局需要N + 1选择几种常见场景。例如:要构建主屏幕,应用必须首先检索用户的chats
对象,然后为每个线程发出chats
请求以获取其信息。如果用户想要在他们的会话中搜索特定字符串,同样的事情:应用程序必须为他们有权访问的每个聊天运行单独的请求,以查看它是否匹配。
我很想设置node.js服务器来对get
树运行经过根身份验证的查询,并完全跳过客户端firebase代码。但是,这首先是在击败Firebase的目的。
有没有办法使用Firebase权限组织这样的数据并避免N + 1选择问题?
答案 0 :(得分:3)
似乎不一定需要避免n + 1个查询,并且Firebase专门设计为在进行n + 1选择时提供良好的性能,尽管对来自关系数据库背景的开发人员来说是违反直觉的。
Firebase 2.4.2 documentation中n + 1的示例后面是一条令人放心的消息:
// List the names of all Mary's groups
var ref = new Firebase("https://docs-examples.firebaseio.com/web/org");
// fetch a list of Mary's groups
ref.child("users/mchen/groups").on('child_added', function(snapshot) {
// for each group, fetch the name and print it
String groupKey = snapshot.key();
ref.child("groups/" + groupKey + "/name").once('value', function(snapshot) {
System.out.println("Mary is a member of this group: " + snapshot.val());
});
});
单独查找每条记录真的可以吗?是。 Firebase协议使用Web套接字,客户端库对传入和传出请求进行大量内部优化。在我们进入成千上万条记录之前,这种方法非常合理。实际上,下载数据所需的时间(即字节数)会使关于连接开销的任何其他问题黯然失色。