Firebase 5与AngularFire2 5:获取数据库真实节点Key的问题
解决Firebase 5 + AngularFire2 5获取真实节点Key的问题
我之前也碰到过一模一样的情况,明明数据库里有Firebase自动生成的长Key,打印出来却只有0、1、2这类序号,这多半是因为数据获取和处理的方式不对,咱们一步步来搞定:
问题根源分析
你提到数据库shopping-cart节点下同时有序号节点和Firebase长Key节点,这说明可能是混合了手动添加的列表式数据和Firebase push()生成的节点。另外,AngularFire2的valueChanges()默认会把Firebase的节点转化为有序数组(用序号作为索引),而不是保留原有的键值对结构,这就是你用Object.keys(obj)拿不到真实Key的核心原因。
正确获取Firebase真实Key的方法
方法1:使用snapshotChanges()订阅数据
这是AngularFire2中获取节点Key最可靠的方式,它会返回包含快照信息的对象,其中就包含Firebase生成的真实Key:
import { AngularFireDatabase } from 'angularfire2/database'; // 注入AngularFireDatabase constructor(private afDb: AngularFireDatabase) {} // 获取shopping-cart下的所有节点及其Key getShoppingCartNodes() { this.afDb.list('shopping-cart').snapshotChanges().subscribe(items => { items.forEach(item => { const realKey = item.payload.key; // 这里就是Firebase生成的长Key const nodeData = item.payload.val(); console.log('真实Key:', realKey, '节点数据:', nodeData); }); }); }
方法2:给valueChanges()添加参数保留快照
如果你习惯用valueChanges(),可以加上{ preserveSnapshot: true }参数来获取包含Key的快照:
this.afDb.list('shopping-cart', { preserveSnapshot: true }).valueChanges().subscribe(snapshots => { snapshots.forEach(snapshot => { const realKey = snapshot.key; const nodeData = snapshot.val(); console.log('真实Key:', realKey); }); });
实现“加入购物车”到指定用户节点的步骤
- 关联用户ID和购物车Key:确保你存在localStorage的购物车ID和Firebase里的真实Key对应上,比如可以在用户创建购物车时,把生成的Key直接存在localStorage或者用户专属的数据库节点里。
- 用真实Key访问指定节点并添加商品:
// 假设从localStorage拿到的购物车真实Key是cartKey addToCart(cartKey: string, product: any) { // 方式1:按商品ID存储(避免重复添加同一件商品) this.afDb.object(`shopping-cart/${cartKey}/products/${product.id}`).set(product); // 方式2:允许重复商品,用push添加到数组 this.afDb.list(`shopping-cart/${cartKey}/products`).push(product); }
额外建议
尽快清理掉shopping-cart下的序号节点,统一用Firebase的push()生成真实Key,混合两种节点结构会让后续的数据操作变得混乱,也容易持续出现Key获取错误的问题。
内容的提问来源于stack exchange,提问作者Dre Jackson
相关产品推荐
相关产品推荐

