【问题标题】:Firestore update multiple properties in object field of a documentFirestore 更新文档对象字段中的多个属性
【发布时间】:2018-07-26 15:54:38
【问题描述】:

所以基于对象字段上的firestore documentation

// Create an initial document to update.
var frankDocRef = db.collection("users").doc("frank");
frankDocRef.set({
    name: "Frank",
    favorites: { food: "Pizza", color: "Blue", subject: "recess" },
    age: 12
});

// To update age and favorite color:
db.collection("users").doc("frank").update({
    "age": 13,
    "favorites.color": "Red"
})
.then(function() {
    console.log("Document successfully updated!");
});

如何更新收藏夹字段的多个属性,例如。

db.collection("users").doc("frank").update({
    "age": 13,
    "favorites.color": "Red",
    "favorites.food": "Burger"
})

控制台中显示一条消息失败:

未处理的错误错误:参数“dataOrField”无效 更新地图。多次指定“收藏夹”字段。

我也尝试过使用 merge: true 选项,例如。

db.collection("users").doc("frank").update({
    "age": 13,
    "favorites": {
        "color": "Red",
        "food": "Burger"
    }
}, {merge: true})

但这会覆盖整个收藏夹字段,这意味着“主题”属性消失了。

有什么想法吗?

这是我的实际代码:

“cardId”来自 POST 请求中的 body.cardId

  return db.runTransaction(t => {
    let user
    let hasDefault = false
    return t.get(userRef).then(userDoc => {
      if (!userDoc.exists) throw new HttpsError('not-found', 'user-not-found')

      user = userDoc.data()
      if (!user.cards || !user.cards[cardId]) throw new HttpsError('not-found', 'card-not-found')

      return updateCustomer(user.cid, { defaultCard: cardId })
    }).then(customer => {
      const prevDefaultId = Object.keys(user.cards).find(cardId => user.cards[cardId] && user.cards[cardId].default)

      let userUpdateData = {}
      if (prevDefaultId && prevDefaultId !== cardId) {
        userUpdateData[`cards.${prevDefaultId}.default`] = false
      }

      userUpdateData[`cards.${cardId}.default`] = true

      return t.update(userRef, userUpdateData, {merge: true})
    })
  })

我已经通过更新两次来解决这个问题:

  return db.runTransaction(t => {
    let user
    let hasDefault = false
    return t.get(userRef).then(userDoc => {
      if (!userDoc.exists) throw new HttpsError('not-found', 'user-not-found')

      user = userDoc.data()
      if (!user.cards || !user.cards[cardId]) throw new HttpsError('not-found', 'card-not-found')

      return updateCustomer(user.cid, { defaultCard: cardId })
    }).then(customer => {
      const prevDefaultId = Object.keys(user.cards).find(cardId => user.cards[cardId] && user.cards[cardId].default)

      if (prevDefaultId && prevDefaultId !== cardId) {
        t.update(userRef, {
          [`cards.${prevDefaultId}.default`]: false
        }, {merge: true})
      }

      return t.update(userRef, {
        [`cards.${cardId}.default`]: true
      }, {merge: true})
    })
  })

【问题讨论】:

  • 您认为“卡片”从何而来?我在您的代码中没有看到任何地方。
  • @DougStevenson 抱歉,忘记重命名该字段,我只是使用了示例,因为这是我从中获取原始代码的地方,但我有自己的字段,“卡片”是我的对象字段我正在尝试更新。 :)
  • 请只显示您遇到问题的确切代码,而不是类似的示例。
  • @DougStevenson 添加了我的代码以及“解决方法”,除非这实际上是这样做的方法,否则我想知道是否不可能以其他方式也许。谢谢

标签: google-cloud-firestore google-cloud-functions


【解决方案1】:

为了updateFirestore 文档中的多个字段,您需要使用字段、值、字段、值...格式:

db.collection("users").doc("frank").update({
    "age", 13, // field, value
    "color, "red" // field, value
})

如果您想更新嵌套字段,您有几个选择。

  1. 使用你提到的点符号:

    db.collection("users").doc("frank").update({
      "age", 13,
      "favorites.color", "Red",
      "favorites.food", "Burger"
     })
    
  2. 让你的“价值”成为一张地图:

    db.collection("users").doc("frank").update({
     "age", 13,
     "favorites", mapOf(
         "color" to "Red",
         "food" to "Burger"
    })
    

【讨论】:

    猜你喜欢
    • 2021-01-24
    • 2018-08-15
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2018-06-11
    • 2018-11-22
    相关资源
    最近更新 更多