Flutter中Firebase数据库按包含指定片段的Key查询数据
Firebase Realtime Database 按Key包含指定片段查询的解决方案
Firebase Realtime Database 的 orderByKey() 查询本身不支持任意位置的包含匹配,它只能做前缀匹配或基于字典序的范围查询。针对你的需求,有两种可行方案:
方案1:修改数据结构(推荐,适合大数据量)
如果可以调整数据库结构,建议把需要匹配的Key片段单独存储为节点的一个字段,这样就能通过 orderByChild() 实现服务器端高效查询。
调整后的数据库结构示例:
"note": { "xyz123abc123": { "content": "你的内容", "keySegment": "abc123" }, "abc123uvw123": { "content": "你的内容", "keySegment": "abc123" } }
对应的查询代码:
String searchForKey = "abc123"; FirebaseDatabase.instance.ref() .child("note") .orderByChild("keySegment") .equalTo(searchForKey) .once() .then((DatabaseEvent databaseEvent) { Map<dynamic, dynamic>? values = databaseEvent.snapshot.value as Map<dynamic, dynamic>?; if (values != null) { values.forEach((key, value) { // 直接处理所有匹配的条目 print("匹配到的key: $key,对应值: $value"); }); } });
方案2:客户端过滤(适合小数据量)
如果无法修改数据结构,只能先拉取所有节点,再在客户端筛选Key包含指定片段的条目:
修改后的代码:
String searchForKey = "abc123"; FirebaseDatabase.instance.ref() .child("note") .orderByKey() .once() .then((DatabaseEvent databaseEvent) { Map<dynamic, dynamic>? values = databaseEvent.snapshot.value as Map<dynamic, dynamic>?; if (values != null) { values.forEach((key, value) { // 客户端过滤Key包含指定片段的条目 if (key.toString().contains(searchForKey)) { print("匹配到的key: $key,对应值: $value"); } }); } });
补充说明
你最初尝试的 equalTo(searchForKey*) 写法不生效,是因为Firebase的查询规则:
equalTo()是精确匹配,不支持通配符;- 若要做前缀匹配,可以用
startAt(searchForKey).endAt(searchForKey + "\uf8ff"),但这只能匹配以abc123开头的Key(比如abc123uvw123),无法匹配xyz123abc123这种Key片段在中间的情况。
内容的提问来源于stack exchange,提问作者Bernhard
相关产品推荐
相关产品推荐

