Firebase实时数据库如何读取数据?

4

我正在开发一款聊天应用程序,其中消息存储在 Firebase 的实时数据库中。现在,如果我创建以下节点 ( chats-Between-A-and-B-Id 是自动生成的聊天室密钥 ),那么当用户 S 在聊天应用程序中打开与 T 的聊天时,数据库将仅读取存储在chats-Between-S-and-T-Id 中的消息,并不会读取其他聊天室的消息!?是吗?如果是这样,这是否会降低定价?

chats-
      chats-Between-A-and-B-Id-
                 messageID1-…
                 messageID2-…
                 messageID3-…
                 ...
      chats-Between-o-and-p-Id-…
      chats-Between-s-and-t-Id-…
      chats-Between-x-and-y-Id-…

或者

如果我像下面所示存储数据,那么如果用户S在聊天应用程序中打开用户T的聊天,则数据库将读取所有消息。

cahts-
      messageID1-…
      messageID2-…
      messageID3-…
      ...

将它们按照下面的方式排序,这样它会读取所有消息并对其进行排序,并在应用程序中向用户显示!? 这将增加价格

if(chat.getReceiver() == senderID && chat.getSender() == receiverId ||
   chat.getReceiver() == receiverId && chat.getSender() == senderID)
                          {
                             (mChatList as ArrayList<Chat>).add(chat) //show chats
                          }

我想知道哪种方法可以省钱。

编辑

我正在使用第二种方法(我从一个聊天应用程序教程中获得的)。我们根据发送方和接收方对消息进行排序,但在阅读了@sharath的答案后,我得出结论,如果我继续使用它,它将读取聊天节点中的每条消息,然后根据发送方-接收方进行排序,如果有来自所有用户的100万条消息,那么它将读取100万条消息并仅为两个用户的部分消息进行排序!这会让我破产。因此,我考虑使用第一种方法,其中我将从chat>>roomIdBetween2Users获取消息,因此它不会读取其他人的聊天,并为我提供安全、可维护和经济实惠的数据库。

这是我的数据库图像,即聊天父节点包含所有用户的所有消息,并按照我在代码中提到的方式进行排序。 chats中已经有大约500多条消息。在未来运营中,这将变得非常危险。enter image description here


1
这更多是安全性问题而非成本问题。基本上,您希望安全规则是这样的,即只有与之相关的用户才能访问其消息。因此,A和B的聊天存储为some_id_a_b,只能由A和B访问,这些用户也不能访问其他用户的聊天记录。我想要类似的安全规则,将一个节点限制为两个ID而不是一个,在文档中也没有提到。 - Lalit Fauzdar
1个回答

3

在不知道你的Firebase数据库结构的情况下回答这个问题有点棘手。我做一个假设并概括这个答案。

Firebase是一种NoSQL数据库,以树形结构或父子方式存储数据。

在使用NoSQL数据库开发任何内容时,您需要创建Firebase DatabaseReference到最深的节点。Firebase查询和读取位于引用节点下的数据。

例如:如果您的Firebase结构如下所示

请参阅Firebase样本结构的此图像

如果要访问用户S的聊天记录,请创建对ID_User_S节点的引用。

注意:如果您创建了顶级节点“Chats”,则快照将返回其下所有子信息

关于定价:是的,您读取的数据越少,支付的价格就越少。如果您引用到尽可能深的节点,则读取的数据量更少。尝试优化所有Firebase查询以达到创建引用的最深节点。

现在来看看你的结构

chats-
      chats-Between-A-and-B-Id-
                 messageID1-…
                 messageID2-…
                 messageID3-…
                 ...
      chats-Between-o-and-p-Id-…
      chats-Between-s-and-t-Id-…
      chats-Between-x-and-y-Id-…

如果您创建了一个对Chats节点的数据库引用,那么每个试图访问聊天的人都将读取其下的每个子项,包括其他聊天。 因此,为了有效使用,请创建一个对chats-Between-A-and-B-Id-的引用,以便您可以获取这两个用户之间的确切消息列表。

希望这个解决方案能给你一个关于Firebase如何读取数据的想法。如果你还有疑问,请发布你的演示Firebase结构。这样我就可以帮你找到合适的解决方案。 - Sharath V Bhargav
嘿@sharath,你的回答非常清晰明了,谢谢。现在在阅读了你的回答之后,我有了一些澄清。所以你的意思是,如果我获取一个子节点的引用,比如parentNode>>anyOneChildNode>>manyChildren,那么如果我获取任何一个子节点的引用,它就不会读取其他的childNode,所以只会读取那个oneChildNode,这样我就要付出比获取parentNode然后排序child更少的代价,因为它会读取每一个child,然后对它们进行排序并显示给我。这意味着我必须读取每一个child,然后无论我如何排序它们来获取其中的一些,我都要付出更多的代价。对吗? - mr. groot
1
是的,你说得对。如果你创建了指向顶级父节点的引用,你的获取查询将读取并返回其下完整的树形结构。这个完整的数据大小是需要计费的。因此,如果你到达最内层的子节点,你可以获得你确切需要的数据,从而避免为不需要的数据获取付费。另外,你还可以使用本地数据库来存储已获取的数据,这样你就不必一遍又一遍地获取数据了。 - Sharath V Bhargav
谢谢!你说得完全正确,感谢你建议我使用本地数据库。我也在考虑使用SQL来保存一些重要的非实时数据快照。我会尝试实现它们。我喜欢你的合作方式,真的很值得赞赏。 - mr. groot
很高兴能帮到你。祝你好运。 - Sharath V Bhargav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接