I am working with Flutter and Cloud Firestore, and I'm stuck on the point where I need to update a nested field inside my collection -> document. Below is the screenshot of my firestore collection structure. I know how to do basic update method like FirebaseFirestore.instance.collection('collection_path').doc('data').update(...)
, however, in my case, the document structure is a bit complex so I need some help in case of performing update method.
Here, I need to change (on a button press) the field status
to true/false
under strategies
array.
I have the access to strategyName
field so that I could get that item in the strategies
array and change it...
What I tried:
ElevatedButton(
onPressed: () async {
// status=true
final value = await FirebaseFirestore.instance
.collection(widget.symbol '_Live')
.doc("data")
.get();
final data = value.data();
final strategies =
data!['strategies'] as List<Map<String, dynamic>>;
final strategy = strategies.firstWhere(
(item) => item['strategyName'] == strategyName,
orElse: () => Map());
strategy['status'] = true;
await FirebaseFirestore.instance
.collection(widget.symbol '_Live')
.doc("data")
.update(data);
},
child: Text("Start"),
),
Obviously, this won't work because here I'm just changing it locally, i.e. not using the Firestore update
method to actually change the field. But I'm confused as to how to update that nested field.
Any leads/help would be really appreciated!
EDIT:
- I did as you told and edited my answer, but now the error is gone but nothing seems to work, i.e. in firestore, there is no change in the data doc.
ERROR
:Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<Map<String, dynamic>>' in type cast
CodePudding user response:
You need to update value
map locally, then store it back:
final value = await FirebaseFirestore.instance
.collection(symbol '_Live')
.doc("data")
.get();
final data = value.data();
final strategies =
data!['strategies'].map((item) => item as Map<String, dynamic>).toList();
final strategy = strategies.firstWhere(
(item) => item['strategyName'] == strategyName,
orElse: () => Map());
strategy['status'] = toggleValue;
await FirebaseFirestore.instance
.collection(symbol '_Live')
.doc("data")
.update(data);
The point is to store the entire value
.
EDIT by Author : Just needed to map each element to Map<String, dynamic>
.