我正在使用Flutter Web和Firebase进行项目,但遇到了问题。我正在尝试更新Firestore中数组中的地图。
使用此:
var val = [];
val.add({'groupUID': groupUID, 'inviteStatus': status});
var userInviteUID;
await users
.document(uid)
.get()
.then((value) => userInviteUID = value.data['inviteUID']);
await invites
.document(userInviteUID)
.updateData({'invites': FieldValue.arrayUnion(val)});
我得到了这个结果: firestore structure
我想做的就是将地图中的1更改为2。我以为它会更新,因为它的值相同,但只是将其添加到数组中。
我在堆栈上四处张望,看到了一些方法来做到这一点,例如复制整个数组并在需要的地方更改它,然后将其重新添加。
但是我想知道是否有办法通过对我的代码进行一些修改来避免这种情况。还请告诉我是否应该使用更好的结构。感谢帮助!
更新:
var ref = invites.document(userData.inviteUID);
ref.get().then((value) async {
var invitesList = value.data['invites'];
switch (status) {
case 1:
break;
case 2:
var index;
invitesList.asMap().forEach((key, value) {
if (value['groupUID'] == groupUID) index = key;
});
invitesList.removeAt(index);
await invites
.document(userData.inviteUID)
.updateData({'invites': FieldValue.arrayUnion(invitesList)});
break;
default:
}
因此,我查看了一些打印语句,发现具有匹配组uid的元素已被删除,但查看Firebase,该数组没有被任何东西覆盖...任何想法?
最终更新:
var ref = invites.document(userData.inviteUID);
ref.get().then((value) async {
var invitesList = value.data['invites'];
switch (status) {
case 1:
break;
case 2:
var index;
invitesList.asMap().forEach((key, value) {
if (value['groupUID'] == groupUID) index = key;
});
invitesList.removeAt(index);
await invites
.document(userData.inviteUID)
.setData({'invites': FieldValue.arrayUnion(invitesList)});
break;
default:
}
通过将updateData更改为setData来解决。
答案 0 :(得分:5)
我在堆栈上四处张望,看到了一些方法来做到这一点,例如复制整个数组并在需要的地方更改它,然后将其重新添加。
这正是修改Firestore文档中数组内容的方式。 Firestore不支持按索引更新数组元素。
答案 1 :(得分:1)
我希望在过去3个月中,在Firestore文档上会有所改变,但看来,道格·史蒂文森(Doug Stevenson)的回答仍然是唯一的答案。
您需要复制整个数组,在本地进行更改,然后在Firebase上发出发布请求。
答案 2 :(得分:0)
setData
如果已经不存在则创建一个新文档,但如果该文档存在,则数据将被覆盖。为防止发生这种情况,如果您希望附加数据,可以使用 SetOptions(merge: true)
:
set(someData, SetOptions(merge: true))
您也可以使用 update
方法并为其提供更新的数据,伪代码如下所示:
List<Map<String, dynamic>> updatedList = [...];
Map<String, dynamic> updatedData = {
'existing_map': updatedList,
};
var collection = FirebaseFirestore.instance.collection('collection');
collection
.doc('doc_id')
.update(updatedData);