如何使用 Ionic 4 删除 Firebase Cloud Firestore 中的元素数组
How to Remove Arrays of Element in Firebase Cloud Firestore using Ionic 4
In My Cloud Firestore
数据库结构如下所示。现在,我想像这样删除基于 Index 0
、Index 1
的索引位置。
const arrayLikedImagesRef = {imageurl: image, isliked: true};
const db = firebase.firestore();
const deleteRef = db.collection('userdata').doc(`${phno}`);
deleteRef.update({
likedimages: firebase.firestore.FieldValue.arrayRemove(arrayLikedImagesRef)
});
});
因为explained here, “bad things can happen when trying to update or delete array elements at specific indexes”. This is why the Firestore official documentation表示arrayRemove()
函数将元素(字符串)作为参数,而不是索引。
如 中所建议,如果您更喜欢使用索引,那么您应该获取整个文档、获取数组、修改它并将其添加回数据库。
您不能使用 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
项目作为字符串。我测试了上面的代码,尽管如此,它似乎仍然有效,但它'最好在类型的使用上保持一致)。
In My Cloud Firestore
数据库结构如下所示。现在,我想像这样删除基于 Index 0
、Index 1
的索引位置。
const arrayLikedImagesRef = {imageurl: image, isliked: true};
const db = firebase.firestore();
const deleteRef = db.collection('userdata').doc(`${phno}`);
deleteRef.update({
likedimages: firebase.firestore.FieldValue.arrayRemove(arrayLikedImagesRef)
});
});
因为explained here, “bad things can happen when trying to update or delete array elements at specific indexes”. This is why the Firestore official documentation表示arrayRemove()
函数将元素(字符串)作为参数,而不是索引。
如
您不能使用 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
项目作为字符串。我测试了上面的代码,尽管如此,它似乎仍然有效,但它'最好在类型的使用上保持一致)。