Firestore data not getting stored in Flutter - flutter

I'm trying to store the user data in firestore, when I'm using the phone number as the document id it's getting stored perfectly but as soon as I changed it to uid it's not. And there were no exceptions been thrown at either. Also I checked if the uid is empty or not too and It's not empty either.
Future addUserToFirestore(String uid) async {
final docUser = FirebaseFirestore.instance
.collection('users')
.doc(uid);
final user = u.User(
name: widget.fullName,
email: widget.email,
gender: widget.gender,
nic: widget.nic,
phoneNumber: widget.phone,
bloodType: widget.bloodType,
dateOfBirth: widget.dateOfBirth,
address: widget.address,
age: int.parse(widget.age));
final json = user.toJson();
await docUser.set(json);
}
When I use .doc('+94${widget.phone}'); instead of .doc(uid); it works fine. But I want to use the uid as document id. Is there a way to get this done?

Try the following method.
Hopefully, this will help.
Future<void> storeUser () async {
var instance = FirebaseFirestore.instance;
await instance.collection("users").doc("uid").set({
// add all of the user data here.
});
}
Else also try:
Future addUserToFirestore(String uid) async {
// add await here as well
final docUser = await FirebaseFirestore.instance
.collection('users')
.doc(uid);
final user = u.User(
name: widget.fullName,
email: widget.email,
gender: widget.gender,
nic: widget.nic,
phoneNumber: widget.phone,
bloodType: widget.bloodType,
dateOfBirth: widget.dateOfBirth,
address: widget.address,
age: int.parse(widget.age));
final json = user.toJson();
await docUser.set(json);
}

Related

FireStore when adding FCM token to User doc, deletes and doesn't store UserId

It's my first time using Firestore Cloud Messaging and I want to get the FCM token for each specific device. For quick development, I added the firebase_auth_ui package, which basically outsources the firebase auth login and registration flow. To capture the user's id and store in their doc, I use a simple function that works fine: and gets the job done:
Future<void> addUserDataToFireStore() async {
CollectionReference users = FirebaseFirestore.instance.collection('users');
String uid = FirebaseAuth.instance.currentUser!.uid;
users.doc(uid).set({
'userId': uid,
// 'displayName': currentUser!.displayName!,
});
}
Now, for some reason when I try to access the registration token, my userId gets deleted. When I try to add the token to the same user doc, the userId gets deleted and the fcm token stays. I generate the token as follows:
generateDeviceToken() async {
String? fcmToken = await FirebaseMessaging.instance.getToken();
final userId = FirebaseAuth.instance.currentUser!.uid;
await FirebaseFirestore.instance
.collection('users')
.doc(userId)
.set({'fcmToken': fcmToken});
}
The issue is when I try to call them both. I can't get the two. The doc will fill with either UserId or FCM, but now both. This is what happens when I try to call both,
Perhaps I should make a method that updates fcm token and not set it everytimg?
When you use "set", the entire document is saved with only that one value. Use "update" to update the document and add your token without removing other content.
generateDeviceToken() async {
String? fcmToken = await FirebaseMessaging.instance.getToken();
final userId = FirebaseAuth.instance.currentUser!.uid;
await FirebaseFirestore.instance
.collection('users')
.doc(userId)
.update({'fcmToken': fcmToken});
}
Future<void> addUserDataToFireStore() async {
CollectionReference users = FirebaseFirestore.instance.collection('users');
String uid = FirebaseAuth.instance.currentUser!.uid;
users.doc(uid).update({
'userId': uid,
// 'displayName': currentUser!.displayName!,
});
}
I ended up changing my logic a little bit. Thanks to #Maniak pointing me in the rigth direction. Solution that worked out was the following:
Future<void> addUserDataToFireStore() async {
final userId = FirebaseAuth.instance.currentUser!.uid;
final userDocRef = FirebaseFirestore.instance.collection('users').doc(userId);
final doc = await userDocRef.get();
if (doc.exists) {
return;
} else {
userDocRef.set({
'userId': userId,
});
}
}
Future<void> generateDeviceToken() async {
String? fcmToken = await FirebaseMessaging.instance.getToken();
final userId = FirebaseAuth.instance.currentUser!.uid;
await FirebaseFirestore.instance
.collection('users')
.doc(userId)
.update({'fcmToken': fcmToken});
}

How to retrieve current user data from firebase?

I tried this way, but i'm getting an error.
The error:
The method 'data' isn't defined for the type 'CollectionReference'. (undefined_method at [myapp] android\app\lib\useracc.dart:32)
void getData() async{
User? user = await FirebaseAuth.instance.currentUser;
var vari =FirebaseFirestore.instance.collection("users");
setState (() {
name = vari.data()['firstname'];
}
);
}
Signup/Register Page
Future<User?> _register(String fname,String lname ,String email, String password) async{
FirebaseAuth _auth = FirebaseAuth.instance;
FirebaseFirestore _firestore = FirebaseFirestore.instance;
try {
UserCredential userCrendetial = await _auth.createUserWithEmailAndPassword(email: emailController.text, password: passwordController.text);
print("Account created Succesfull");
userCrendetial.user!.updateDisplayName(fname);
userCrendetial.user!.updateDisplayName(lname);
await _firestore.collection('users').doc(_auth.currentUser!.uid).set({
"firstname": fname,
"lastname" : lname,
"email": email,
"uid": _auth.currentUser!.uid,
});
return userCrendetial.user;
} catch (e) {
print(e);
return null;
}
}
This is the user account from where i want to fetch info:
Please help. I'm struck here a long time.
You should retrieve the currentUser document then access its data:
void getData() async{
var vari = await FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser.uid)
.get();
setState (() {
name = vari.data()['firstname'];
});
}
if you've saved your user's details in firestore and its document id is the same as that of user ID (which is preferred for ease of access and control), then:
var vari =FirebaseFirestore.instance.collection("users").doc(user!.uid).get();
This gets the document of the user, and the type is DocumentSnapshot.
Map<String,dynamic> userData = vari as Map<String,dynamic>;
now userData is stored in form of Map. suppose you want to access their 'name', so the syntax now goes like userData['name'].
Similarly other fields can be accessed from variable. It's preferred to store userData in a Provider to access it's contents anywhere in your app.
Full code snippet
void getData() async{
User? user = await FirebaseAuth.instance.currentUser;
var vari =FirebaseFirestore.instance.collection("users").doc(user!.uid).get();
Map<String,dynamic> userData = vari as Map<String,dynamic>;
setState (() {
name = userData['firstname']; //or name = userData['name']
}
);
}

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()

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()!;

Flutter: How to add many fields in firestore using one document without overwriting

I'm having a problem on my project right now. I know, many already posted this issue but I really dont know how to implement it in my code. I want to do is, to add multiple data in firestore fields using one document. In the fields, have a field name "Issue" and inside "Issue" I have many data in it. Everytime I add a new data in that document, it overwrites the data in the field. How to add the data without overwriting, please help.
Here is my code:
_saveIssueToActivities(dynamic data) async {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final FirebaseUser user = await _firebaseAuth.currentUser();
try {
DocumentReference ref = db.collection('ACTIVITIES').document(user.uid);
return ref.setData({
'Issue': {
'User_ID': '',
'Name_ofUser': '${data['Name_ofUser']}',
'Help_Description': '${data['Help_Description']}',
'Help_DatePosted:': '',
'Help_Location': '',
'Help_TypeNeeded': '${data['Help_TypeNeeded']}',
'Help_NotificationID': '',
}
});
} catch (e) {
print(e);
}
}
Here is my Database Structure:
Link to my db pic
Try with:
Future<dynamic> addDataToFirestore(dynamic data) async {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final FirebaseUser user = await _firebaseAuth.currentUser();
DocumentReference ref = db.collection('ACTIVITIES').document(user.uid);
dynamic datatoSubmit = [{
'User_ID': '',
'Name_ofUser': '${data['Name_ofUser']}',
'Help_Description': '${data['Help_Description']}',
'Help_DatePosted:': '',
'Help_Location': '',
'Help_TypeNeeded': '${data['Help_TypeNeeded']}',
'Help_NotificationID': ''
}];
//Do some debugging with the datatypes or which type of data you have in the firebase document.
await ref.updateData({'Issue': FieldValue.arrayUnion(datatoSubmit)});
}
Or
Future<dynamic> addDataToFirestore(dynamic data) async {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final FirebaseUser user = await _firebaseAuth.currentUser();
DocumentReference ref = db.collection('ACTIVITIES').document(user.uid);
dynamic datatoSubmit = {
'User_ID': '',
'Name_ofUser': '${data['Name_ofUser']}',
'Help_Description': '${data['Help_Description']}',
'Help_DatePosted:': '',
'Help_Location': '',
'Help_TypeNeeded': '${data['Help_TypeNeeded']}',
'Help_NotificationID': ''
};
//Do some debugging with the datatypes or which type of data you have in the firebase document.
await ref.updateData({'Issue': FieldValue.arrayUnion(datatoSubmit)});
}
Here is my result with the 2nd one example :