问题
Using flutter, when updating an array with 2 or more consecutive identical values, firestore only adds one.
Example :
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)});
}
When executing this function 2 times, the array "nauseaLevel" in firestore will only add one "pain" value and ignore the second.
the array nauseaTime works as expected as the values are different.
回答1:
According to the official documentation regarding updating elements in an array:
arrayUnion()adds elements to an array but only elements not already present.
So there is no way you can add duplicate elements within an array in Cloud Firestore using arrayUnion() function.
To avoid a misunderstanding, however, you can add duplicate elements within an array but only if you read the entire array client side, do the additions (with all duplicates) and then write it back to the database.
回答2:
You can't use arrayUnion to manage an array that must contain duplicates, as you can tell from the definition of arrayUnion.
What you can do instead is read the document, modify the array in the client to be what you want (including duplicates), and write the array field back to Firestore. You can do this atomically with a transaction.
回答3:
I wrote an article on handling nested objects with Flutter and Firestore and it has some details on how to do this.
Here's my example of retreiving an array, updating it, and saving it back to 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())
});
}
And my Exercise and Set Classes:
Exercise
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();
}
Set
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();
}
来源:https://stackoverflow.com/questions/56110491/firestore-doesnt-store-two-identical-values-while-updating-an-array