使用 flutter,当更新具有 2 个或更多连续相同值的数组时,firestore 只会添加一个。
示例:
void updateValue() {
var now = [new DateTime.now()];
int pain =5;
Firestore.instance.collection('Patient').document('bC2ML7LaQ1fWGOl37ZUq').collection('Symptom').document('2H6e99Bvrz6h0HBzgnyg')
.updateData({ 'nauseaLevel' : FieldValue.arrayUnion([pain]), 'nauseaTime':FieldValue.arrayUnion(now)});
}
当执行该函数2次时,firestore中的数组“nauseaLevel”只会添加一个“pain”值,而忽略第二个。
数组恶心时间按预期工作,因为值不同。
根据官方文档关于更新数组中的元素:
将元素添加到数组中,但仅添加尚未存在的元素。arrayUnion()
因此,您无法使用
arrayUnion()
函数在 Cloud Firestore 的数组中添加重复元素。
但是,为了避免误解,您可以在数组中添加重复元素,但前提是您在客户端读取整个数组,进行添加(包含所有重复项),然后将其写回数据库。
您不能使用 arrayUnion 来管理必须包含重复项的数组,从 arrayUnion 的定义可以看出。
您可以做的是读取文档,将客户端中的数组修改为您想要的值(包括重复项),然后将数组字段写回 Firestore。您可以通过事务以原子方式完成此操作。
我的 Angular 项目也有同样的问题,但是我在应用程序中创建了一个临时数组,我首先将数据推送到该数组中,然后将临时数组添加到 Firestore 中并且它起作用了
tempOrder: order = [];
chosenMeal(meal: string, price: number){
this.tempOrder.push( {meal, price} );
this.db.collection('tables').doc(this.table.propertyId).update({order:(this.tempOrder)})
}
正如您从示例中看到的,首先我将所选餐食以及价格作为对象添加到我的临时数组
tempOrder
中,然后在下一行中,我使用来自 的数据更新 firestore 中的
order
数组tempOrder
数组
你可以在firestore中看到想要的结果
我写了一篇关于 使用 Flutter 和 Firestore 处理嵌套对象 的文章,其中详细介绍了如何执行此操作。
这是我检索数组、更新数组并将其保存回 Firestore 的示例:
void AddObjectToArray() {
Exercise exercise;
Set newSet;
Firestore.instance
.collection("exercises")
.document("docID")
.get()
.then((docSnapshot) => {
newSet = Set(10, 30),
exercise = Exercise.fromMap(docSnapshot.data),
exercise.sets.add(newSet),
Firestore.instance.collection("exercises").document("docID").setData(exercise.toMap())
});
}
还有我的练习和课程:
锻炼
class Exercise {
final String name;
final String muscle;
List<dynamic> sets = [];
Exercise(this.name, this.muscle);
Map<String, dynamic> toMap() => {"name": this.name, "muscle": this.muscle, "sets": firestoreSets()};
List<Map<String,dynamic>> firestoreSets() {
List<Map<String,dynamic>> convertedSets = [];
this.sets.forEach((set) {
Set thisSet = set as Set;
convertedSets.add(thisSet.toMap());
});
return convertedSets;
}
Exercise.fromMap(Map<dynamic, dynamic> map)
: name = map['name'],
muscle = map['muscle'],
sets = map['sets'].map((set) {
return Set.fromMap(set);
}).toList();
}
设置
class Set {
final int reps;
final int weight;
Set(this.reps, this.weight);
Map<String, dynamic> toMap() => {"reps": this.reps, "weight": this.weight};
Set.fromMap(Map<dynamic, dynamic> map)
: reps = map["reps"].toInt(),
weight = map["weight"].toInt();
}
const [myA, setmyA] = useState([])
const subAnswer = async (ant) => {
if (currentQuestion < 25) {
myA.push({
submittedanswer: ant.ant,
isCorrect: ant.isCorrect,
},)
const docRef = doc(db, 'quiz1', `${submittedansid}`)
await updateDoc(docRef, {
gevaar: myA })
}
}
这适用于我的反应应用程序
根据文档“
arrayUnion()
将元素添加到数组中,但仅添加尚未存在的元素。”。有两种方法可以规避它,一种方法是您可以通过读取整个数组客户端在数组中添加重复元素,进行添加(重复),然后将其写回数据库,但这绝对不是最佳的。您可以做的另一个“技巧”是通过使用一些客户端逻辑,您可以检查相同的对象是否已经存在,在这种情况下稍微修改该对象,然后执行arrayUnion()