【问题标题】:ERROR Error: Reference.set failed: First argument contains an invalid key ($key) in propertyERROR 错误:Reference.set 失败:第一个参数在属性中包含无效键 ($key)
【发布时间】:2020-04-07 18:59:49
【问题描述】:

我是 Angular 的新手,我正在尝试在 Angular 项目上实现添加到购物车的功能。 这是添加到购物车的功能:

  async addToCart(product: Productsobj) {
    let cartId = await this.getOrCreateCartId();
    let item$ = this.db.object(
      "/shopping-carts/" + cartId + "/items/" + product.$key
    );
    item$
      .valueChanges()
      .pipe(take(1))
      .subscribe((p: any) => {
        if (p) item$.update({ quantity: p.quantity + 1 });
        else item$.set({ product: product, quantity: 1 });
      });
  }

这是错误:

core.js:6014 错误错误:Reference.set 失败:第一个参数在属性“shopping-carts.-Lw2GnUrgt9nMyNKznlW.items.-KrqgOLs07ZkbapP4EGi.product”中包含无效键 ($key)。键必须是非空字符串,并且不能包含“.”、“#”、“$”、“/”、“[”或“]”

我尝试将函数更改为:

  async addToCart(product: Productsobj) {
    let cartId = await this.getOrCreateCartId();
    let item$ = this.db.object(
      "/shopping-carts/" + cartId + "/items/{{product.$key}}"// changed product.$key
    );
    item$
      .valueChanges()
      .pipe(take(1))
      .subscribe((p: any) => {
        if (p) item$.update({ quantity: p.quantity + 1 });
        else item$.set({ product: product, quantity: 1 });
      });
   }

现在得到错误:

core.js:6014 错误错误:未捕获(承诺中):错误:Reference.child 失败:第一个参数是无效路径 = "/shopping-carts/-Lw2GnUrgt9nMyNKznlW/items/{{product.$key}} ”。路径必须是非空字符串,并且不能包含“.”、“#”、“$”、“[”或“]”

如何正确解开product.$key

编辑: product 参数是一个对象:console.log(product)

product:product 更改为productName:product.title 后,错误消失了,firebase 显示:

有没有办法在 firebase 中获取整个对象?

【问题讨论】:

  • 你能用 addToCart func 接收到的产品参数的值更新问题吗?
  • 是的,我已经更新了@Ramesh

标签: javascript angular firebase firebase-realtime-database angularfire


【解决方案1】:

尝试以下方法:

let key = product["$key"];
let item$ = this.db.object("/shopping-carts/" + cartId + "/items/" + key);

使用方括号访问属性$key。此外,最好将属性 $key 更改为 key

【讨论】:

  • 是的,我尝试了同样的错误,看来问题不在于路径,而是 ` item$.set({ product: product, quantity: 1 }); ` 这里的论点 product 没有展开。有没有办法将一个对象作为一个整体发送到 firebase 。编辑:当我更改 product:product.$key product:product.title 时它可以工作
  • 但我希望将整个对象发送到 firebase。有办法吗? @彼得
  • 如果我添加product:product 会给我错误,否则如果product:product.titleproduct:product.category 运行良好且没有错误但我只能在firebase 中获得上述数据(即标题、类别等)。我想要firebase中的整个产品对象。检查问题以获取更新的图片@peter
  • @GeorgeMenezes 你可以做到set({productName:product.title,productCategory:product.category, productKey : product.key})
  • 如果你添加整个对象,那么在检索时你应该做product.product.category
【解决方案2】:

使用product.payload.val()为产品对象设置产品属性如下:

async addToCart(product){
  let cartId= await this.getOrCreateCartId();
  let item$=  this.db.object('/shopping-carts/' + cartId + '/items/' + product.key);
  item$.valueChanges().pipe(take(1)).subscribe((item:any) => {
    if(item!=null) {
      item$.set({product: product.payload.val(), quantity: item.quantity + 1})
    }
    else item$.set({product: product.payload.val(), quantity: 1});
  });
}


【讨论】:

    【解决方案3】:

    Productsobj接口的定义如下:

    export interface Productsobj
    {
       key: string; 
       title: string; 
       price: number; 
       category: string; 
       imageUrl: string;
    }
    

    也就是说,不要使用“$key”,而是使用“key”。有了这个,下面的代码就可以工作了

    async addToCart(product: Productsobj) {
       const cartId = await this.addOrGetCartId();
       const item$ = this.db.object('/shopping-carts/' + cartId + '/items/' + product.key);
       item$.valueChanges().pipe(take(1)).subscribe( (item:any) => {
          if (item) item$.update({quantity: item.quantity + 1});
          else item$.update({product: product, quantity: 1});
     });
    }
    

    Firebase 不允许您使用以 $ 字符开头的键。如果您尝试在数据库中添加一个新对象(使用 firebase 控制台),其键为“$key”,则会标记以下错误: '路径包含无效字符'。这就是您在 Angular 应用程序中遇到错误的原因。

    【讨论】:

      【解决方案4】:

      我已经解决了这个问题。

      之前(有错误)

        async addToCart(product: Product) {
          let cartId = await this.getOrCreateCartId();
          let item$ = this.getItem(cartId, product.$key as string);
          item$
            .valueChanges()
            .pipe(take(1))
            .subscribe((item: any) => {
              if (item == null)
                item$.set({
                  product: product,
                  quantity: 1,
                });
              else item$.update({ quantity: item.quantity + 1 });
            });
        }
      

      之后(无错误)

        async addToCart(product: Product) {
          let cartId = await this.getOrCreateCartId();
          let item$ = this.getItem(cartId, product.$key as string);
          item$
            .valueChanges()
            .pipe(take(1))
            .subscribe((item: any) => {
              if (item == null)
                item$.set({
                  product: {
                    title: product.title,
                    category: product.category,
                    price: product.price,
                    imageUrl: product.imageUrl,
                  },
                  quantity: 1,
                });
              else item$.update({ quantity: item.quantity + 1 });
            });
        }
      

      只需将隐式产品对象更改为显式产品对象

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-18
        • 1970-01-01
        • 2019-09-08
        • 1970-01-01
        • 1970-01-01
        • 2015-01-31
        相关资源
        最近更新 更多