Firebase如何根据作为集合的孙级字段值检索对应文档?
问题原因
你当前查询不生效的核心原因是:Firebase Realtime Database 的 equalTo 匹配规则是完全匹配字段的完整值,你的barcodes是数组类型,equalTo('88888')会尝试寻找barcodes字段整个值等于字符串88888的节点,自然无法匹配到数组中包含该值的节点。
解决方案
方案1:调整数据结构(推荐,性能最优)
将barcodes从数组格式改为键值对映射格式,把条码值作为键,值固定为true,调整后的结构如下:
{ "products": { "dfwojozijowjfoije": { "barcodes": { "12345": true, "5678": true }, "productName": "someProduct" }, "sdafsdasdfasdfadsf": { "barcodes": { "99999": true, "88888": true }, "productName": "someProduct2" } } }
调整后查询代码修改为:
await firebase .database() .ref('products') .orderByChild('barcodes/88888') .equalTo(true) .on('value', snapshot => { setProductName(snapshot.val()) })
使用该方案需要提前为路径配置索引,在你的Firebase Realtime Database规则中添加如下配置,避免全表扫描:
{ "rules": { "products": { ".indexOn": "barcodes" } } }
方案2:客户端过滤(仅适合数据量极小的场景)
如果暂时无法修改数据结构,可以先查询全量products数据,在客户端做过滤:
await firebase .database() .ref('products') .on('value', snapshot => { const products = snapshot.val() || {} const matchedProduct = Object.values(products).find(product => product.barcodes?.includes('88888') ) setProductName(matchedProduct) })
该方案的缺点是会拉取全量商品数据,数据量增大后会严重浪费带宽和查询性能,仅适合测试或数据量小于百条的场景。
内容的提问来源于stack exchange,提问作者Jimmy Geers
相关产品推荐
相关产品推荐

