How to send Map<String,bool> to cloud Firestore in Flutter - flutter

We have a Map declared as follows:
Map<String, bool> _selection = {};
It contains data as follows:
key = 'Messi'
value = 'true'
We wanted to send the data containing in the Map _selection.
Right now we are trying using a method defined as given below:
Future<Map<String, dynamic>> votedown() async {
_selection.forEach((key, value) {
Map<dynamic, dynamic> comdata = <dynamic, dynamic>{
'criteriaName': key,
'isChecked': value,
};
return comdata;
});
}
We are sending data to firestore as:
DocumentReference ref =
FirebaseFirestore.instance.collection('posts').doc();
await ref.set({
'Players': {
'Football': {
await votedown(),
}
}
});
But it is giving error as:
ArgumentError (Invalid argument: Instance of '_CompactLinkedHashSet<Map<String, dynamic>>')
Please help me to solve this?
Desired Output in Firestore in 'posts' collection:
--> Players
--> Football
--> PlayerName : Messi
isStriker : true

It seems the problem is in brackets {} surrounding the await downvote(). As the method is returning a map object already, if you put into the brackets you will have set of map nested object. Such objects are not in types available in the Firestore (reference) and this is reason of the error.
I do not have a playground to test it, but please try bellow:
DocumentReference ref =
FirebaseFirestore.instance.collection('posts').doc();
await ref.set({
'Players': {
'Football': await votedown(),
}
});

Related

Problem while reading document from firestrore in flutter

I am new to Firebase I want to read all data of document here is how i am trying to read
This is my function to get data.
Future<List<AgencyModel>> getAgencyData() async {
List<AgencyModel> agencyListModel = [];
try {
agencyListModel = await _db.collection('colelctionName')
.doc('myDoc')
.snapshots()
.map((doc)=> AgencyModel.fromJson(doc.data()!)).toList();
print('List : ${agencyListModel.length}');
return agencyListModel;
} catch (e) {
debugPrint('Exception : $e');
rethrow;
}
}
This is how i am calling the above function
getAgencyDetails() async {
List<AgencyModel> data = await fireStoreService.getAgencyData();
print('Data : ${data.first}');}
and this is my models class fromjson function
factory AgencyModel.fromJson(Map<String, dynamic> json) {
return AgencyModel(
agencyName: json['agencyName'],
agencyContact: json['agencyContact'],
agencyAddress: json['agencyAddress'],
cnic: json['cnic'],
agencyContactDetails: json['agencyContactDetails'],
certificatesUrl: json['certificatesUrl'],
locationUrl: json['locationUrl'],
earning: json['earning'],
processing: json['processing'],
onHold: json['onHold']);}
I am not getting any error or exception, Also these two print statements does not work not display anything not even the Strings List : and Data : i.e
print('List : ${agencyListModel.length}');
print('Data : ${data.first}');}
UPDATE:
According to the documentation:
https://firebase.google.com/docs/firestore/query-data/get-data#dart_1
It is necessary to distinguish whether you want to retrieve the data only once or listen to changes over the document in real time.
It seems to me like you want to accomplish 1. case that you only want to retrieve data once. In that case.
You should change:
agencyListModel = await _db.collection('collectionName')
.doc('myDoc')
.snapshots()
agencyListModel = await _db.collection('collectionName')
.doc('myDoc')
.get()

How to convert map into array to firestore? flutter

I have a users id I want to add it to firestore, like this
['GEcuHm3ICpWlEzfq1Z2tAjI2LII3', 'GEcuHm3ICpWlEzfq1Z2tAjI2LII3' ...]
I tried multiple ways but it didn't work
List membersListUid = [];
Future createGroup() async{
GroupRoomModel newGroup = GroupRoomModel(
groupName: groupName.text,
groupRoomId: uuid.v1(),
owner: userModel.uid,
membersList: controller.membersList,
membersListUid: controller.membersListUid.cast() // <---
);
}
...
Future createGroupFunc() async{
GroupRoomModel newGroup = GroupRoomModel(
groupName: groupName.text,
groupRoomId: uuid.v1(),
owner: userModel.uid,
membersList: controller.membersList,
membersListUid: controller.membersListUid.map((e)=> e).toList() //<---
);
...
Maybe this helps to understand the code
//Controller class
Map<String, dynamic>? userMap;
onSearch() async {
await _fireStore
.collection('users')
.where("email", isEqualTo: searchedMembers.text)
.get()
.then((value) {
userMap = value.docs[0].data();
});
update();
}
membersListUid.add({
"uid": userMap!['uid']
});
It's still gives me map within array.
THE PROBLEM:
membersListUid is a List of Maps. That is why you get an array of Maps in your database.
You need to get the actual value of the uid from each Map by using the uid key to get the value from the map.
THE SOLUTION:
Update this line:
membersListUid: controller.membersListUid.map((e)=> e).toList()
to this below:
controller.membersListUid.map((e)=> (e as Map<String, dynamic>)['uid']).toList()

How to get value with key from a Map<String, dyanmic> in Flutter

I am new to flutter and Firestore, and still leaning.
I have been trying to print a single value from a Map<String, Dynamic>. When I print the whole map it works but when tried to print a single value with key, it produces a null error.
getUsersFromFireStore(String appUid) async {
List<Map<String, dynamic>> list = [];
await instance.collection('Users').where('refDocument', isEqualTo: appUid).get()
.then((querySnapshotOne) {
return querySnapshotOne.docs[0].reference.collection('Data').orderBy('timeStamp', descending: true).get();
}).then((querySnapshotTwo) {
if(querySnapshotTwo.size > 0){
querySnapshotTwo.docs.forEach((doc) {
String id = doc.id;
list.add(doc.data()); // Here is the problem
// print(doc.data().toString()); produces {age:24, name: Hari Ram}
// But doc.data()['name'] doesn't work, gives null error
});
}
});
return list;
}
Please help. Thanks in advance.
** UPDATE ** when tried with doc.data['name'] as per the comments, it shows following error:
doc.data['name'] // This should solve your problem
Remove () after the data keyword.
i.e. print(doc.data['name'])
UPDATE :
Try doc.get('name')

Unable to use a Future value - Flutter/Dart

I've fetched a json object and deserialized it and then returned it too.
I want to use this in another file.
I'm unable to assign the values that I'm getting in the first step.
Here are all the codes...
Service
Future getGeoPoints(String accessToken, String tripId) async {
String requestUrl;
var response = await get(
Uri.parse(requestUrl),
headers: {
'Authorization': "Bearer $accessToken",
},
);
if (response.statusCode == 200) {
Map<String, dynamic> responseBody = json.decode(response.body);
GetGeoPoints geoPoints = GetGeoPoints.fromJson(responseBody);
List listOfGeoPoints = [];
for (var geoPoint in geoPoints.geoPoints) {
listOfGeoPoints.add(
{
'latitude': geoPoint.latitude,
'longitude': geoPoint.longitude,
'timestamp': geoPoint.timeStamp,
},
);
}
// print('List of geo points: ' + '$listOfGeoPoints');
return listOfGeoPoints;
} else {
throw Exception('Failed to load data from server');
}
}
File where I need the above values
List routeCoordinates;
Future<void> getValues() async {
getGeoPoints(widget.accessToken, widget.tripId)
.then((value) => routeCoordinates = value);
}
When I run the app, routeCoordinates is null but when I hotreload, it contains the value.
I want to have the values as soon as the screen starts. What is the right way to assign the values here?
I've also tried this:
routeCoordinates = getGeoPoints...
It throws error..
Please help.. Thanks..
The function getGeoPoints() is an asynchronous one. But on the other file, you are not using the await keyword, instead you are using then(). So your code is not waiting for that function to return value.
Try using below code,
List routeCoordinates;
Future<void> getValues() async {
routeCoordinates = await getGeoPoints(widget.accessToken, widget.tripId);
}
Let us know how it went.
You need to use a FutureBuilder to define a behaviour depending on the state of the request. You'll be able to tell the widget what to return while your app is waiting for the response to your request. You can also return a specific widget if you get an error(if your user is offline, for example).
Edit: I've linked the official docs but give this article a read if it's not clear enough.

Getting a map from Firestore and setting it to a new map

I have two methods the first one for getting a map stored in Firestore
Future daysMap(FirebaseUser user, String packageCode, int totalDays) async {
await users.document(user.uid).collection('myPackages')
.document(packageCode)
.get().then((doc){
// print(doc.data['DaysMap']);
return doc.data['DaysMap'];
});
}
It works correctly and prints out the map. The second method is for setting the map from Firestore to a new map in order to loop on it.
currentWorkout(FirebaseUser user, String packageCode,totalDays) async {
Map<dynamic, dynamic> days = await daysMap(user, packageCode, totalDays);
print(days);
}
When i print our the new map 'days' it always prints null.
Try using the async/await style.
Future daysMap(FirebaseUser user, String packageCode, int totalDays) async {
DocumentSnapshot doc = await users.document(user.uid).collection('myPackages').document(packageCode).get();
return doc.data['DaysMap'];
}