【问题标题】:How to search by array-like data in Firebase Realtime Database?如何在 Firebase 实时数据库中搜索类似数组的数据?
【发布时间】:2021-03-02 23:25:42
【问题描述】:

我正在开发一个带有Firebase Realtime Database 设施的颤振应用程序。这是一种聊天应用程序。这里我有一个名为chat_room 的根节点,它将保存所有聊天室。每个chat_room 都将保存有关其成员的信息,即聊天中的人。下面是我现在的数据结构

我的要求是,当我通过电子邮件搜索时,我应该能够获得与该电子邮件关联的所有 chat_rooms。例如,我需要知道电子邮件 ID someone@test.com 注册的所有chat_rooms。

问题是,我现在知道我不能用我当前的结构来做到这一点,我将数据保存为array。阅读this 我知道使用SETArray 的更好替代品,因为它允许我们执行此类搜索。所以也许这就是我需要的结构。

 chat_room
      chatroom1
        chat_mode: "supplier",
        last_message: "test",
        timestamp: 1223334
        members:
            email1: true
            email2: true
      chatroom2
        chat_mode: "supplier",
        last_message: "test",
        timestamp: 1223334
        members:
            email1: true
            email2: true

下面是我用来通过电子邮件搜索的代码,它什么也没给我。

final DatabaseReference reference = FirebaseDatabase.instance.reference().child('chat_room');
reference.orderByChild("members").equalTo("someone@test.com").once();

目前,这是我将数据保存到 chat_room 的方式。

//Create chat_room
  Future<String> createChatRoom({String lastMessage, String chatMode, List<ChatMember> members}) async {
    
    var newChatRoomRef = _chatRoomReference.push();
    var newChatRoomKey = newChatRoomRef.key;
    await newChatRoomRef.set({
      'last_message': lastMessage,
      'chat_mode': chatMode,
      'members': [members[0].email, members[1].email],
      'timestamp': DateTime.now().millisecondsSinceEpoch,
      
    });

    return newChatRoomKey;
  }

无论是SET数据结构还是Array或者HashMap或者不管是什么,我的要求是通过电子邮件搜索chat_rooms。

  1. 如果SET 数据结构是这个问题的答案,我怎样才能将它保存到firebase?如何准备数据以便正确发送?请随时使用我上面的createChatRoom 方法,并告诉我如何通过SET 而不是Array
  2. 如何执行搜索?
  3. 如果set 不是答案,那是什么?

感谢您的支持。

编辑

根据@Frank 的建议,我这样写了我的代码,复制了他提供的确切代码。

//Create chat_room
  Future<String> createChatRoom(
      {String lastMessage, String chatMode, List<ChatMember> members}) async {
    var newChatRoomRef = _chatRoomReference.push();
    var newChatRoomKey = newChatRoomRef.key;
    await newChatRoomRef.set({
      'last_message': lastMessage,
      'chat_mode': chatMode,
      'members': [members[0].email, members[1].email],
      'timestamp': DateTime.now().millisecondsSinceEpoch,
    });
    var userChatRoomsRef =
        FirebaseDatabase.instance.reference().child('chat_room');
    members.forEach((member) {
      userChatRoomsRef
          .child(member.userID.toString() + "-userID")
          .child(newChatRoomKey)
          .set(true);
    });

    return newChatRoomKey;
  }

那个,这是它生成的结构。 (请注意,30-userID 和 50-userID 是实际的用户 ID,因为我没有使用 Firebase Auth 的 UID)

无论如何,我真的不确定这是否是我应该拥有的正确结构。

编辑 2

根据@Frank 的编辑,这就是我制作我的代码和它生成的数据库结构的方式。

//Create chat_room
  Future<String> createChatRoom(
      {String lastMessage, String chatMode, List<ChatMember> members}) async {
    var newChatRoomRef = _chatRoomReference.push();
    var newChatRoomKey = newChatRoomRef.key;
    await newChatRoomRef.set({
      'last_message': lastMessage,
      'chat_mode': chatMode,
      'members': [members[0].email, members[1].email],
      'timestamp': DateTime.now().millisecondsSinceEpoch,
    });
    var userChatRoomsRef =
        FirebaseDatabase.instance.reference().child('user_chatrooms');
    members.forEach((member) {
      userChatRoomsRef
          .child(member.userID.toString() + "-userID")
          .child(newChatRoomKey)
          .set(true);
    });

    return newChatRoomKey;
  }

现在仍然确定这是否是正确的,因为我现在正在转移到另一个节点。

【问题讨论】:

    标签: android ios firebase flutter firebase-realtime-database


    【解决方案1】:

    是的,我在链接答案中给出的方法是允许搜索特定用户的聊天室。您最终会得到一个辅助数据结构,将用户映射到他们关联的聊天室。

    为了保存这个额外的数据结构,你循环遍历子元素,基本上写出你已经拥有的相反的东西。比如:

    var newChatRoomRef = _chatRoomReference.push();
    var newChatRoomKey = newChatRoomRef.key;
    await newChatRoomRef.set({
      'last_message': lastMessage,
      'chat_mode': chatMode,
      'members': [members[0].email, members[1].email],
      'timestamp': DateTime.now().millisecondsSinceEpoch,  
    });
    var userChatRoomsRef = FirebaseDatabase.instance.reference().child('user_chatrooms')
    members.forEach((member) {
      userChatRoomsRef.child(member.uid).child(newChatRoomKey).set(true);
    });
    

    【讨论】:

    • 感谢您的回复。我更改了我的代码。它生成的代码和数据库结构都在我编辑的问题中。我真的不确定这是否是您想要生成的。请检查。
    • 糟糕。正如我对您链接的问题的回答中所解释的那样,那应该是一个不同的顶级节点。我更新了答案中的代码。
    • 我已经对我的代码进行了编辑,在我编辑的答案中发布了数据库结构和代码。在那里,您似乎创建了一个名为user_chatrooms 的新node。但我仍然看不到通过电子邮件搜索聊天的方法。这是对的吗?或者我必须通过用户 ID 搜索 user_chat 房间才能找到相关的聊天室?那也很好。请指教。
    • 啊,如果你想通过电子邮件访问它们,你需要使用(编码的)电子邮件作为密钥,而不是我上面使用的 UID。好吧...或者将电子邮件存储为值,而不是像我在回答中所做的那样true
    • 完美。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 2017-04-04
    相关资源
    最近更新 更多