您不能使用FieldValue 按索引删除数组项。相反,您可以使用 transaction 删除数组项。使用事务可确保您实际上写回了您期望的确切数组,并且可以与其他写入者打交道。
例如(我这里使用的参考是任意的,当然你需要提供正确的参考):
db.runTransaction(t => {
const ref = db.collection('arrayremove').doc('targetdoc');
return t.get(ref).then(doc => {
const arraydata = doc.data().likedimages;
// It is at this point that you need to decide which index
// to remove -- to ensure you get the right item.
const removeThisIndex = 2;
arraydata.splice(removeThisIndex, 1);
t.update(ref, {likedimages: arraydata});
});
});
当然,正如上面代码中所指出的,只有当您实际在事务本身内部时,您才能确定您将要删除正确的索引——否则您获取的数组可能与您最初选择的索引位于。所以要小心!
也就是说,鉴于FieldValue.arrayRemove 不支持嵌套数组(因此您不能将多个映射传递给它以删除),您可能会问该怎么办。在这种情况下,您只需要实际检查值的上述变体(此示例仅适用于单个值和固定对象类型,但您可以轻松地将其修改为更通用):
const db = firebase.firestore();
const imageToRemove = {isliked: true, imageurl: "url1"};
db.runTransaction(t => {
const ref = db.collection('arrayremove').doc('byvaluedoc');
return t.get(ref).then(doc => {
const arraydata = doc.data().likedimages;
const outputArray = []
arraydata.forEach(item => {
if (!(item.isliked == imageToRemove.isliked &&
item.imageurl == imageToRemove.imageurl)) {
outputArray.push(item);
}
});
t.update(ref, {likedimages: outputArray});
});
});
(我确实注意到在您的代码中您使用的是原始布尔值,但数据库将 isliked 项目作为字符串。我测试了上面的代码,尽管如此,它似乎仍然有效,但最好是在使用类型时保持一致)。