Firebase Firestore:从文档数组中追加/删除项目

Posted

技术标签:

【中文标题】Firebase Firestore:从文档数组中追加/删除项目【英文标题】:Firebase Firestore: Append/Remove items from document array 【发布时间】:2018-04-07 04:09:37 【问题描述】:

我正在尝试从 Firestore 文档内的数组中追加/删除项目,但每次替换整个数组而不是追加新值时。我已经尝试了以下两种方法:

batch.setData(["favorites": [user.uid]], forDocument: bookRef, options: SetOptions.merge())

batch.updateData(["favorites": [user.uid]], forDocument: bookRef)

我知道我可以使用对象/字典代替数组,但这意味着存储不相关的其他数据(例如密钥),我所需要的只是存储在数组中的 ID。这是目前在 Firestore 中可以实现的吗?

【问题讨论】:

【参考方案1】:

不。这是不可能的。

在像 Cloud Firestore 这样的环境中,数组往往会出现问题,理论上许多客户端可以同时从数组中追加或删除元素 - 如果指令以稍微不同的顺序到达,您最终可能会出现不合时宜的情况。边界错误,损坏的数据,或者只是一个非常糟糕的时间。因此,您要么需要使用字典(可以在其中指定单个键),要么需要替换整个数组。

【讨论】:

我就是这么想的。感谢您确认/澄清托德! @LucaVentura 您可以在这篇 firebase 博客文章 firebase.googleblog.com/2014/04/… 中看到“阵列是邪恶的”的原因:) @cutiko 感谢您的链接。无论如何,在我的情况下使用字典效果更好,因为如果不从键访问它,我将无法轻松删除它:)【参考方案2】:

实际上,如今这是可能的。最新更新db.collection.updateData 方法实际上将新项目附加到数组而不是替换它。 用法示例见Firebase documentation。

如果需要手动操作,可以使用

FieldValue.arrayUnion([user.uid])

【讨论】:

刚刚在我的项目中使用了这个,只有在添加 '.updateData([ "name" : FieldValue.arrayUnion([self.colleagueName])' 后才有效 我正在尝试从文档上的数组中删除一个值: document.updateData([ "memberIds": FieldValue.arrayRemove(memberIds) ]) 。但是每次我尝试访问这个数组的值时,删除的值也会出现在数据中。【参考方案3】:

更新数组中的元素

如果您的文档包含数组字段,您可以使用 arrayUnion() 和 arrayRemove() 来添加和删除元素。 arrayUnion() 将元素添加到数组中,但只添加不存在的元素。 arrayRemove() 删除每个给定元素的所有实例。

let washingtonRef = db.collection("cities").document("DC")

// Atomically add a new region to the "regions" array field.
washingtonRef.updateData([
    "regions": FieldValue.arrayUnion(["greater_virginia"])
])

// Atomically remove a region from the "regions" array field.
washingtonRef.updateData([
    "regions": FieldValue.arrayRemove(["east_coast"])
])

See documentation here

【讨论】:

以上是关于Firebase Firestore:从文档数组中追加/删除项目的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 SwiftUI 从 Firebase / Firestore 中删除文档

Firebase Firestore 读取和定价

Firebase Firestore - 使用多个“数组包含”过滤数据

Firebase Firestore从数组Javascript查询

如何使用 react-redux-firebase 从 firestore 获取子集合

Firebase Cloud Firestore 在 Flutter 中获取地图数组