How to convert map into array to firestore? flutter - 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()

Related

How can i manually add document-fields into local QueryDocumentSnapshot List

i have the following list
List <QueryDocumentSnapshot> globalVideosUrls = [] ;
for example if we use the following
FirebaseFirestore.instance.collection('users')
.limit(1).get().then((value){
globalVideosUrls.add(value)
});
it will add as expected
but what if i want to manually add the following data into globalVideosUrls
document id
00dcb026-3163-4ca0-859e
fields
'videoType':'peace'
'url':'url'
.
globalVideosUrls.add(????)
You have to replace the type "QueryDocumentSnapshot" with QuerySnapshot and then you will get multiple docs and with there data also try this If any questions then ask.
thanks🙏.
List<QuerySnapshot> globalVideosUrls = [];
List<String> videoUrlList = [];
await FirebaseFirestore.instance
.collection('users')
.get()
.then((value) {
globalVideosUrls.add(value);
});
globalVideosUrls.forEach((element) {
element.docs.forEach((docELe) {
print("data:- ${docELe.data()}");
Map map = docELe.data() as Map;
videoUrlList.add(map['url']);
});
});

How to loop through Instance of '_MapStream<QuerySnapshotPlatform, QuerySnapshot<Map<String, dynamic>>>'?

static List categoryList() {
final categorySnapshots = FirebaseFirestore.instance
.collection('categories')
.orderBy('name')
.snapshots();
List categories = [];
categorySnapshots.map((snapshot) => snapshot.docs.map((doc) {
print(snapshot.toString());
categories.add(doc.data()['name']);
}));
print(categories);
return categories;
}
Categories is empty.
How to populate it with the data from snapshots?
I added a new collection called "school", there're two items added inside the document.
void getMessagesTest() async{
QuerySnapshot querySnapshot = await _firestore.collection('school').orderBy('age',descending: true).get();
final allData = querySnapshot.docs.map((doc) => doc.data()).toList();
print(allData);
}
I used my code, and it works. Could you please remove ".where" and try it again?
You could chain where and orderBy together. Please see my code below. Reference link => Using Where and Order by different fields in Firestore query
void getMessagesTest() async{
QuerySnapshot querySnapshot = await _firestore.collection('school').orderBy('age', descending: true).where('age', isGreaterThan: 17).get();
final allData = querySnapshot.docs.map((doc) => doc.data()).toList();
print(allData);
}
Using the below code might help
you can convert the snapshot to Map<String,dynamic> by using the following function:
static Post fromSnap(DocumentSnapshot snap) {
var snapshot = snap.data() as Map<String, dynamic>;
}

Flutter How to reach into Future<DocumentSnapshot<Map<String, dynamic>>> inner map

I need help with my flutter code which involves firebasefirestore.
This is my code. I'd like to retrieve from the database the image_url from the map.
final userData = FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser.uid)
.get();
But in userData is not a map exactly.
It is a Future<DocumentSnapshot<Map<String, dynamic>>>.
This is what get returns . My question is, how do I scope into the Map<String, dynamic> ?
I mean to get the userData['image_url']... ? Because I get this error:
The operator '[]' isn't defined for the type 'Future<DocumentSnapshot<Map<String, dynamic>>>'.
Thanks alot!
As shown in the Firebase documentation on getting a document, that'd be:
final docRef = db.collection("users").doc(FirebaseAuth.instance.currentUser.uid);
docRef.get().then(
(DocumentSnapshot doc) {
final data = doc.data() as Map<String, dynamic>;
// ...
},
onError: (e) => print("Error getting document: $e"),
);
You can also use await as Timur commented, in which case it'd be:
final docRef = db.collection("users").doc(FirebaseAuth.instance.currentUser.uid);
DocumentSnapshot doc = await docRef.get();
final data = doc.data() as Map<String, dynamic>;
// ...

Firestore how to save data in a subcollection

I have a collection users where every user has his own document. Now I want to create a subcollection to store more data related to a specific user.
So far my Code looks like this:
class DatabaseService {
Future isUserRegistered(String uid) async{
return await FirebaseFirestore.instance.collection('users')
.where('uid', isEqualTo: uid)
.get();
}
Future registerNewUser(email, password, uid) async{
return await FirebaseFirestore.instance.collection('users')
.doc(uid).set(
{
"email": email,
"password": password,
"uid": uid,
"token": -1,
"userGoal": false,
"userGender": false,
},
);
}
Future saveToRemote() async{
Map<String, dynamic> data = UserManager.userdata;
return await FirebaseFirestore.instance.collection('users')
.doc(data['uid'])
.set(data);
}
class UserManager {
static Map<String, dynamic> userdata = null;
}
How can I store data in a subcollection?
EDIT
I created a new save function but instead of storing data in a subcollection in the document with the current uid, firestore creates a new document named 'uid'. How to fix that?
Future saveInSubcollectionToRemote() async{
Map<String, dynamic> data = UserManager.userWeights;
return await FirebaseFirestore.instance.collection('users')
.doc('uid')
.collection('weights')
.doc(data['userWeight'])
.set(data);
}
Saving to a subcollection is no different from saving to a top-level collection. You build a path to the CollectionReference under the user's document and call add like this:
FirebaseFirestore.instance
.collection('users').doc(uid)
.collection('subcollection').add(
{
"field": value,
},
);

Breaking changes with cloud_firestore 2.0?

I am using CloudFirestore with my app.
Everything was working fine and since the 2.0.0 version, I encounter errors that I didn't before.
Here is the code :
final _fireStore = FirebaseFirestore.instance
.collection('familyAccounts')
.doc(id)
.collection('users');
final DocumentSnapshot doc1 = await _fireStore.doc('user1').get();
final DocumentSnapshot doc2 = await _fireStore.doc('user2').get();
final _fireStore2 = FirebaseFirestore.instance
.collection('familyAccounts')
.doc(id)
.collection('users')
.doc('user1')
.collection('vocList');
await _fireStore2.get().then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
_carnetVoc1.add(
VocList(
ref: doc['ref'],
titre: doc['titre'],
creation: doc['dateCreation'],
modification: doc['dateModification'],
wordId: doc['mots']),
);
});
});
final _fireStore3 = FirebaseFirestore.instance
.collection('familyAccounts')
.doc(id)
.collection('users')
.doc('user2')
.collection('vocList');
await _fireStore3.get().then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
_carnetVoc2.add(
VocList(
ref: doc['ref'],
titre: doc['titre'],
creation: doc['dateCreation'],
modification: doc['dateModification'],
wordId: doc['mots']),
);
});
});
_accountEmail = id;
Map user1 = doc1.data()!;
Map user2 = doc2.data()!;
_user1 = User(
userId: user1['userId'],
avatar: user1['avatar'],
classe: user1['classe'],
teacherCode: user1['teacherCode'],
carnetVoc: _carnetVoc1);
_user2 = User(
userId: user2['userId'],
avatar: user2['avatar'],
classe: user2['classe'],
teacherCode: user2['teacherCode'],
carnetVoc: _carnetVoc2);
The lines :
Map user1 = doc1.data()!;
Map user2 = doc2.data()!;
no longer work with the new version : I get this :
"A value of type object can't be assigned to a variable of type Map".
I don't understand what has changed... as all this was working fine before.
Anyone encountered this too ?
there is a document to perform the migration: https://firebase.flutter.dev/docs/firestore/2.0.0_migration/
Referring to it, you should add type <Map<String, dynamic>> explicitly.
In your case you need to change:
final DocumentSnapshot doc1 = await _fireStore.doc('user1').get();
final DocumentSnapshot doc2 = await _fireStore.doc('user2').get();
to:
final DocumentSnapshot<Map<String,dynamic>> doc1 = await _fireStore.doc('user1').get();
final DocumentSnapshot<Map<String,dynamic>> doc2 = await _fireStore.doc('user2').get();
Also, cloud_firestore: 2.0.0 promotes type safety, hence I'd suggest you using Map concrete types for your variables:
Map<String,dynamic> user1 = doc1.data()!;
Map<String,dynamic> user2 = doc2.data()!;