I want when a new user registers then in the userProfile collection there I should be able to set a unique id to each user like
P-_____
If you are using firebase authentication then you can do the following
final String Uid = FirebaseAuth.instance.currentUser.uid;
final firestore = FirebaseFirestore.instance;
firestore.collection(collectionPath).doc("P-"+Uid).set(data);
Alternatively, if you are not using FirebaseAuth then you can do the following
final String Uid = FirebaseAuth.instance.currentUser.uid;
final firestore = FirebaseFirestore.instance;
firestore.collection(collectionPath).doc("P-"+getRandomString(10)).set(data); //random string with 10 charecter
Code to generate a random string
const _chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
Random _rnd = Random();
String getRandomString(int length) => String.fromCharCodes(Iterable.generate(
length, (_) => _chars.codeUnitAt(_rnd.nextInt(_chars.length))));
The add method adds the new document to your collection with a unique auto-generated ID. If you'd like to specify your own ID, call the set method on a DocumentReference instead:
CollectionReference users = FirebaseFirestore.instance.collection('users');
Future<void> addUser() {
return users
.doc('ABC123')
.set({
'full_name': "Mary Jane",
'age': 18
})
.then((value) => print("User Added"))
.catchError((error) => print("Failed to add user: $error"));
}
Calling set with a id that already exists on the collection will replace all the document data.
Related
I want to stream documents from my collection orders.
Here I stream all documents in my collection orders where the parameter progress is equal to pool.
This is how I do it:
Stream<List<Order>> streamOrderPool() {
final FirebaseAuth auth = FirebaseAuth.instance;
final User? user = auth.currentUser;
final uid = user!.uid;
var ref = _db.collection('orders').where('progress', isEqualTo: 'pool');
return ref.snapshots().map(
(list) => list.docs.map((doc) => Order.fromJson(doc.data())).toList());
}
What I want to do is to remove all documents where the parameter dismissedIds contains uid.
This is how I solved it in a futurebuilder:
Future<List<Order>> getOrdersPool() async {
final FirebaseAuth auth = FirebaseAuth.instance;
final User? user = auth.currentUser;
final uid = user!.uid;
var ref = _db.collection('orders').where('progress', isEqualTo: 'pool');
var snapshot = await ref.get();
var data = snapshot.docs.map((s) => s.data());
var orders = data.map((d) => Order.fromJson(d));
var orderslist = orders.toList();
orderslist.removeWhere((order) => order.dismissedIds.contains(uid));
orderslist.sort((b, a) => a.startDate.compareTo(b.startDate));
return orderslist;
}
How do I get the same result in a streambuilder, is it possible to use removeWhere somehow? How do I remove all documents from stream where dissmissedIds contains uid?
I'm trying to compare the text inputted by user to my firestore collection.
But when I tried this code:
docSnapshot.data()!.containsValue(currentStudPass);
where currentStudPass is a String that contains the User ID which is 184-0055
It works but it's trying to search for all the fields value that the user has,
for example I tried "Test Section" as a password, it will return true.
I want to exclude all fields except the password: or just use containsValue for password: field. But I don't have any idea how to do that I'm new to Flutter.
I tried:
docSnapshot.data()!.containsValue('password: $currentStudPass');
var docSnapshot = await collection.doc("$currentStudId/password").get();
But it doesn't work.
Here's my firestore db.
static Future<bool> checkPass(String passArg) async {
// method to check if the users password is correct
var collection = FirebaseFirestore.instance.collection('users');
var docSnapshot = await collection.doc("$currentStudId").get();
try {
passCheck =
docSnapshot.data()!.containsValue(currentStudPass);
return passCheck;
} catch (e) {
// If any error
return false;
}
try this if this works.
static Future<bool> checkPass({String? id, String? passArg}) async {
final collection = FirebaseFirestore.instance.collection('users');
final docs = await collection.doc(id!).get();
final Map<String,dynamic> map = docs.data() as Map<String,dynamic>;
// you can direct it since the result from contains is bool
return map['password'].toString().contains(passArg!);
// Edit : you can use operator == to know exact input
// return map['password'] == passArg!;
}
I am trying to fetch the role of the currently authenticated user stored in users collection. What I am trying to achieve is at login time, query the user role by traversing fetching the user's document in the collection and sifting through the fields or checking all documents and returning the field role as a string.
Collection and document snapshot(excuse the terminology):
All documents in users collection have same fields for now.
Please how do I go about writing this type of query in flutter? I have tried using AuthResult in my service and FirebaseAuth to get current user(but no way to access the fields in the document).
Thanks.
String role;
getUserRoleWithFuture() async {
String currID = await _authService.getCurrentUID();
String mRole;
Firestore.instance.collection(USERS_REF).document(currID).get().then((doc) {
mRole = doc.data['role'];
print(mRole);
});
return mRole;
}
Future<String> getUserRoleWithStream() async {
String currID = await _authService.getCurrentUID();
String sRole;
Firestore.instance
.collection(USERS_REF)
.document(currID)
.snapshots()
.listen((DocumentSnapshot ds) {
if (ds.exists) {
sRole = ds.data['role'];
print('with stream:\t$sRole');
}
});
return sRole;
}
In the method getUserRoleWithStream() I am trying to retrieve the value printed out like role = getUserRoleWithStream() but instead get this in console a value of type Future<String> can't be assigned to a variable of type string.
How do I get this value using either the stream (cos it constantly observes the collection) or using the other method and use it in my widget?
Thanks again.
This is the working solution, in case anyone else runs into this. I appreciate the effort made into helping me understand the issue but here's the answer:
String role;
getUserRoleWithFuture() async {
String currID = await _authService.getCurrentUID();
String mRole;
Firestore.instance.collection(USERS_REF).document(currID).get().then((doc) {
mRole = doc.data['role'];
print(mRole);
});
return mRole;
}
Future<String> getUserRoleWithStream() async {
String currID = await _authService.getCurrentUID();
String sRole;
Firestore.instance
.collection(USERS_REF)
.document(currID)
.snapshots()
.listen((DocumentSnapshot ds) {
if (ds.exists) {
sRole = ds.data['role'];
print('with stream:\t$sRole');
}
});
return sRole;
}
Well first off, I assume the AuthResult.user.uid and your user's collection user's id is same. So that once you have the user from AuthResult, you can query your firestore collection to get the user's role as follows.
Future<String> getUserRole(String uid) async {
DocumentSnapshot ds = await Firestore.instance.collection('users').document(uid).get();
return ds.data['role'];
}
In Dart, how do you retrieve the auto-generated ID within a collection's document?
I have a collection called "users" that has auto ID documents with the users details. How do you retrieve that ID?
ID eg: yyHYmbDelykMPDWXHJaV
I'm trying to get this id. When the document is first created, when user is first created, the user.uid is stored in it's collection.
I can retrieve all the data from the users database, which I don't want:
void getData() {
databaseReference
.collection('users')
.getDocuments()
.then((QuerySnapshot snapshot) {
snapshot.documents.forEach((f) => print('${f.data}'));
});
}
I can get a future reference for the current user's user.uid but that still doesn't give me the unique document ID.
Future<DocumentReference> getUserDoc() async {
final FirebaseAuth _auth = FirebaseAuth.instance;
final Firestore _firestore = Firestore.instance;
FirebaseUser user = await _auth.currentUser();
DocumentReference ref =
_firestore.collection('users').document(user.uid);
print(ref);
return ref;
}
Is it possible to search the user.uid against the database users and retrieve the ID that way?
To get the auto generated id, you can just call the document method on whatever collection you're trying to get a document from and the returned value will have a getter for documentID
final userDocument = usersCollection.document();
final documentID = userDocument.documentID;
You usually do this when you first want to create a document. To retrieve the documentID after you've created it, I'd add it to the user document itself:
userDocument.setData({
documentID: documentID,
/* ... */
});
Instead of using the auto generated documentID though, I personally use the firebase user's uid property just because it ties it back to Firebase auth
// user is a FirebaseUser
final userDocument = usersCollection.document(user.uid);
userDocument.setData({
uid: user.uid,
// ...displayName, email, etc.
});
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 :