Adding an array to a document in firebase from flutter - flutter

I'm trying to add a new collection with two values in it's document, one is a string and the other is an array.
it worked when I added the string without the array, so my problem is with the array.
this is the function I wrote to set the new collection
void addCategory({required String addedCategory, required List tags}) {
FirebaseFirestore.instance.collection("Category").doc(addedCategory).set({
'name': addedCategory,
'Tags': [tags]
}).then((value) {
emit(CategoryAdded());
});
}
and this the calling
UserCubit.get(context).addCategory(
addedCategory: 'Resturants', tags: ['Italian', 'Romanian']
);
If anyone can help I'll be thankful.

Your tags is already a list and it should not be sent as list<list>
void addCategory({required String addedCategory, required List tags}) {
FirebaseFirestore.instance.collection("Category").doc(addedCategory).set({
'name': addedCategory,
'Tags': [tags], // remove this line
'Tags': tags, // add this line
}).then((value) {
emit(CategoryAdded());
});
}

Related

How to rename axios FormData array when submitting

Is there something I can do to prevent axios from renaming my FormData field name when it is an array.
For example:
I have an array of images I am posting using the field name of images. When I post this, I notice in the payload of my browser the field becomes multiple fields, i.e. it becomes images.0 and images.1.
In other words it looks like axios is renaming the field and making multiple fields with names like images.N.
Is there any way to avoid this renaming? On the server side I am using node with Nestjs and multer.
My Nestjs controller function expects a field name images but it throws an "unexpected field" error because axios renames the fields to images.0 and then images.1.
NestJS controller function that fails (note the field name):
#Post()
#UseGuards(AuthGuard('jwt'))
#UseInterceptors(FilesInterceptor('images', 30, { dest: './uploads' }))
create(
#Body() body: CreateAssetDto,
#User() user: RequestUser,
#UploadedFiles() files: Array<Express.Multer.File>,
) {
console.log(files, body, user.userId);
//return this.assetsService.create(body, user.userId);
}
NestJs controller function that works (note the use of the field name images.0):
#Post()
#UseGuards(AuthGuard('jwt'))
#UseInterceptors(FilesInterceptor('images.0', 30, { dest: './uploads' }))
create(
#Body() body: CreateAssetDto,
#User() user: RequestUser,
#UploadedFiles() files: Array<Express.Multer.File>,
) {
console.log(files, body, user.userId);
//return this.assetsService.create(body, user.userId);
}

Flutter FireStore Create, Read and Update Array with a Map Object

Fairly new to Flutter and FireStore, I'm having trouble finding examples or explanations on how to add Maps to an Array (specifically, Creating the initial Array with a Map, then Reading then Adding more Maps to the collection of the Notes Array).
I have an Event Class for scheduling events and that is working very well. What I'm trying to add is a "Notes" field that would allow an some Administrator to add Notes on one day then come back and add to that Event another set of notes as things change. I don't want to "overwrite" the previous Notes, just keep adding more Notes to the Array of notes.
Specific questions:
How do I Create the "Array" when adding the entry into FireStore using Flutter?
How do I Read the data in the "Array" when it's coming back as a set of "Map fields" in Flutter?
How do I just Add to the Array with a new Note? (I think this needs FieldValue.arrayUnion([someMap]) but I'm not certain as this appears to avoid any overwriting.
The page section here shows writing it out but little else: https://firebase.google.com/docs/firestore/manage-data/add-data#data_types
Below is an example of the FireStore structure I'm trying to create.
Has anyone done this before and do you have some direction you can provide? The Firebase documentation in this space is thin...
To create an new document with array in firestore:
FirebaseFirestore.instance.collection('path/to/collection').add(
{ 'notesArray': [
{'date': 'sometime', 'notes': 'somenotes', 'user': 'someuser'}
]},
SetOptions(merge: true),
);
// or
FirebaseFirestore.instance.collection('path/to/collection').add(
{ 'notesArray': []}, // for an empty array
SetOptions(merge: true),
);
To read the data:
FirebaseFirestore.instance.doc('company').get().then((value) {
final doc = value.data()!;
print(doc['lname']); // should print Gethsemane
print(doc['notesArray'] as List); // should print notes array
final notes = doc['notesArray'] as List;
for (final note in notes) {
print(note['date']);
print(note['notes']);
print(note['user']);
}
// or
for (int i = 0; i < notes.length; i++) {
print(notes[i]['date']);
}
});
Add new data to notes array. Simply use FieldValue.arrayUnion.
E.g
FirebaseFirestore.instance.doc('path/to/doc').set(
{
'notesArray': FieldValue.arrayUnion([
{'date': 'sometime', 'notes': 'somenotes', 'user': 'someuser'}
]),
},
SetOptions(merge: true),
);
// I used set method along with setOptions in order not to
// override other fields (e.g modifiedBy field)
Keep in mind that if your array is going to be very large, it is better to store the notes as a subcollection.
##EDIT##
If you want to update a nested array, you can use the dot notation.
class SchedulerEvents {
final List<Map<String, dynamic>>? notes;
SchedulerEvents({required this.notes});
}
// lets assume we have data like this that we want to update
final data = SchedulerEvents(
notes: [
{'date': 'sometime', 'notes': 'somenotes', 'user': 'someuser'},
],
);
FirebaseFirestore.instance.doc('path/to/doc').set(
{
'schedulerEvents.notes': FieldValue.arrayUnion([data.notes![0]]),
// or
'schedulerEvents.notes': FieldValue.arrayUnion(data.notes![0]),
// 'schedulerEvents.lname: 'test', // to update other fields
},
SetOptions(merge: true),
);
// we used dot notation to update fields here.

how to add and edit data at the same time into local list

i have these fields from Firstore doc
'name': 'Alex'
'age': 20
'product': 'cars'
and here i get data
List <QueryDocumentSnapshot> finalResultsForMessgse = [] ;
future getData(){
FirebaseFirestore.instance.collection("product").get().then((value) {
value.docs.forEach((data) {
finalResultsForMessgse.add(data); // here it will add data as written
exactly in firstore into my local list
but how can manual edit fields into my local list ..like following
finalResultsForMessgse.add(
'name':value.get('name')+'add extra Letters'
'age':value.get('age')+'add extra Letters'
'product':value.get('product')+'add extra Letters'
)
use List<dynamic> finalResultsForMessgse = []; for final result list.
FirebaseFirestore.instance.collection('product').get().then((value) {
value.docs.forEach((data) {
var doc = data.data();
finalResultsForMessgse.add({
'name': '${doc['name']} + add extra Letters',
'age': '${doc['age']} + add extra Letters',
'product': '${doc['product']} + add extra Letters',
});
});
});
To show the result list:
for (var item in finalResultsForMessgse) Text('${item['name']}'),

Flutter dropdown can't have duplicate values? But unfortunately I have those as it is fetching from an API

My dropdown is having duplicate values as it is fetching Pincode data from an API. Can someone help me to fix this error as the dropdown cant have duplicate values? How to stop duplicate values while fetching the data from the API?enter image description here
You can convert your list to set and then again back to list for to delete duplicated values. Set doesnt contain duplicated values. For more check out documentation of set
void main() {
final myList = [
{
'a': 'apple',
'name':'sam',
'age': 41,
},
{
'a': 'apple',
'name':'alex',
'age': 43,
},
{
'a': 'ban',
'name':'robby',
'age': 41,
}
];
var uniqueIds = myList.map((o) => o["a"]).toSet().toList();
print(uniqueIds);
}
Mapping the list with specific key and then => conversion of toSet() and toList() solves my problem

How to update more than one field in sub document?

{
movies: [
{
_id,
title,
rating
}
]
}
I want to update title or rating or both only if exists.
my query should be something like this
Movies.findOneAndUpdate('movies._id': movieId, {
movies.$.rating: rating,
movies.$.title: title
});
But it doesn't support multiple positional operator.
The possible solution I thought was to send entire movie object and replace it as
Movies.findOneAndUpdate('movies._id': movieId, {
movies.$: movie
});
I don't want to replace entire object or I don't want to send entire movie object from frontend.
Please guide me with an optimised solution.
Movies.findOneAndUpdate({'movies._id': movieId},{$set:{title:req.body.title}} {
movies.$: movie
});
You can do it with array filters https://jira.mongodb.org/browse/SERVER-1243
db.movies.update(
{},
{$set: {“movies.$[i].title”: "newTitle", “movies.$[i].rating”: 4}},
{arrayFilters: [{i._id: "movieId"}]}}
)