如何在 Firebase 实时数据库中搜索类似数组的数据?
Posted
技术标签:
【中文标题】如何在 Firebase 实时数据库中搜索类似数组的数据?【英文标题】:How to search by array-like data in Firebase Realtime Database? 【发布时间】:2021-03-02 23:25:42 【问题描述】:我正在开发一个带有Firebase Realtime Database
设施的颤振应用程序。这是一种聊天应用程序。这里我有一个名为chat_room
的根节点,它将保存所有聊天室。每个chat_room
都将保存有关其成员的信息,即聊天中的人。下面是我现在的数据结构
我的要求是,当我通过电子邮件搜索时,我应该能够获得与该电子邮件关联的所有 chat_room
s。例如,我需要知道电子邮件 ID someone@test.com
注册的所有chat_room
s。
问题是,我现在知道我不能用我当前的结构来做到这一点,我将数据保存为array
。阅读this 我知道使用SET
是Array
的更好替代品,因为它允许我们执行此类搜索。所以也许这就是我需要的结构。
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_room
s。
-
如果
SET
数据结构是这个问题的答案,我怎样才能将它保存到firebase?如何准备数据以便正确发送?请随时使用我上面的createChatRoom
方法,并告诉我如何通过SET
而不是Array
。
如何执行搜索?
如果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;
现在仍然确定这是否是正确的,因为我现在正在转移到另一个节点。
【问题讨论】:
【参考方案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
。
完美。谢谢。以上是关于如何在 Firebase 实时数据库中搜索类似数组的数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中保存实时 Firebase 数据库中的数据?