Firebase查询List<String>包含值的技术问询及数据识别处理
Firebase中查询List的"contains"操作说明与JSON数据解析
一、针对List的Contains查询操作
不管你用的是Cloud Firestore还是Realtime Database,我都给你梳理清楚对应的实现方式:
1. Cloud Firestore 实现
Firestore原生支持数组的包含查询,直接用arrayContains操作符就能搞定。比如你要从SHOPPING_LIST集合里找出所有共享给特定用户的清单,代码示例(以Flutter SDK为例):
FirebaseFirestore.instance .collection("SHOPPING_LIST") .where("sharedWithUsers", arrayContains: "kPLZpp809gePpBiBojsngjZdg6A3") .get() .then((snapshot) { snapshot.docs.forEach((doc) => print("匹配的清单:${doc.data()}")); });
几个关键注意点:
arrayContains是精确匹配,只能找数组里和目标值完全一致的元素,不支持模糊搜索- 如果要同时匹配多个值,用
arrayContainsAny,但最多传10个值 - 数组元素的类型必须和查询值严格一致,比如都是String类型,不能混存数字或对象
2. Realtime Database 实现
Realtime Database没有原生的数组contains查询,因为它的数组是按索引存储的。这里有两种可行方案:
- 推荐方案:转成键值对结构
把sharedWithUsers从数组改成{ "用户ID": true }的结构,这样就能用orderByChild+equalTo来查询:firebase.database().ref("SHOPPING_LIST") .orderByChild("sharedWithUsers/kPLZpp809gePpBiBojsngjZdg6A3") .equalTo(true) .once("value") .then((snapshot) => console.log(snapshot.val())); - 客户端过滤(不推荐)
如果必须保留数组结构,只能先拉取所有清单数据,再在客户端遍历数组判断是否包含目标值。但数据量大时会非常低效,尽量别用。
二、你的JSON数据解析
先把你提供的JSON格式化后展示(保留原内容的截断部分):
{ "SHOPPING_LIST": { "kPLZpp809gePpBiBojsngjZdg6A3:228c1e5b-fe11-4f06-ad32-c54734044a5e": { "listId": "kPLZpp809gePpBiBojsngjZdg6A3:228c1e5b-fe11-4f06-ad32-c54734044a5e", "listName": "Lista de la compra de Jesús Lunar Pérez", "owner": "kPLZpp809gePpBiBojsngjZdg6A3", "pendingListElements": 0, "sharedWithUsers": [ "kPLZpp809gePpBiBojsngjZdg6A3" ] } }, "users": { "kPLZpp809gePpBiBojsngjZdg6A3": { "label": "Jesús Lunar Pérez", "userId": "kPLZpp809gePpBiBojsngjZdg6A3", "userInfo": { "nick..." } } } }
结构拆解
- 根节点分两个核心模块:
SHOPPING_LIST(购物清单集合)和users(用户集合) - SHOPPING_LIST:
- 每个子节点的键就是清单的唯一ID(和
listId字段值一致) - 清单对象的字段:
listId:清单的全局唯一标识listName:西班牙语的清单名称,翻译过来是"Jesús Lunar Pérez的购物清单"owner:清单所有者的用户IDpendingListElements:待完成的清单项数量,当前是0sharedWithUsers:共享该清单的用户ID数组,目前只有所有者自己
- 每个子节点的键就是清单的唯一ID(和
- users:
- 子节点的键是用户的唯一ID(和
userId字段值一致) - 用户对象的字段:
label:用户的显示名称userId:用户的全局唯一标识userInfo:用户的额外信息,内容被截断为"nick..."
- 子节点的键是用户的唯一ID(和
结合查询的实际应用
比如你要找所有属于Jesús Lunar Pérez的购物清单,不管是用Firestore的where("owner", isEqualTo: "kPLZpp809gePpBiBojsngjZdg6A3"),还是Realtime Database的orderByChild("owner").equalTo("kPLZpp809gePpBiBojsngjZdg6A3")都能轻松实现。而如果要查共享清单,就用前面提到的数组查询方案。
内容的提问来源于stack exchange,提问作者Chave
相关产品推荐
相关产品推荐

