ERROR Error: Reference.set failed: First argument contains an invalid key ($key) in property

ERROR Error: Reference.set failed: First argument contains an invalid key ($key) in property

我是 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 ERROR Error: Reference.set failed: First argument contains an invalid key ($key) in property 'shopping-carts.-Lw2GnUrgt9nMyNKznlW.items.-KrqgOLs07ZkbapP4EGi.product'. Keys must be non-empty strings and can't contain ".", "#", "$", "/", "[", or "]"

我尝试将函数更改为:

  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 ERROR Error: Uncaught (in promise): Error: Reference.child failed: First argument was an invalid path = "/shopping-carts/-Lw2GnUrgt9nMyNKznlW/items/{{product.$key}}". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"

如何正确打开 product.$key

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

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

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

尝试以下操作:

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

使用括号访问 属性 $key。如果您将 属性 $key 更改为 key

也更好

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

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});
  });
}


使用以下定义 Productobj 接口:

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”,则会标记以下错误: 'Path contains invalid characters'。这就是您的 Angular 应用出现错误的原因。

我已经解决了问题

之前(有错误)

  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 });
      });
  }

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