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.
});
Related
Trying to fetch a document name "abcd".
await _firestore
.collection("users")
.where("name", isEqualTo: _auth.currentUser?.uid)
.get()
.then((value) {
setState(() {
userMap = value.docs[0].data();
});
});
.uid is not providing the document "abcd". How can I get it?
Only need the name of document.
That name "abcd" is the document id in your Firestore database, if you need to access it you will need to set the document id as its name which you look in the Firestore database :
await _firestore
.collection("users")
.doc("abcd")
.get() ; // this will get you the abcd document
and if you want to query your collection based on uid, and get the document information from it, first you will need a field called "name" which it's value id the user's uid, then :
await _firestore
.collection("users")
.where("name", isEqualTo: _auth.currentUser?.uid)
.get(querySnapshot).then(() {
final document = querySnapshot.docs.first;
print(document.id); // this will print abcd
});
How can I reference the collection in the document I auto-id in Firebase?
final CollectionReference _olanaklar5 = _database
.collection("Kategoriler")
.doc("Hoteller")
.collection("5_Yıldızlı")
.doc() //======> here
.collection("Olanaklar");
You can get list all document id with doc.id
List<String> _listDocId = [];
await fireStore
.collection("Kategoriler")
.doc("Hoteller")
.collection("5_Yıldızlı")
.get()
.then((QuerySnapshot querySnapshot) {
for (var doc in querySnapshot.docs) {
_listDocId.add(doc.id);
}
});
and query in list doc id
for (var id in _listDocId) {
final CollectionReference _olanaklar5 = _database
.collection("Kategoriler")
.doc("Hoteller")
.collection("5_Yıldızlı")
.doc(id)
.collection("Olanaklar");
}
If you're using Firebase auth, it's preferred to keep User's UID as doc, else you can use .where() as a query to match the fields in all documents. But as the app scales, it will be a hectic process and will consume many reads.
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.
I'm having an issue with retrieving and storing single data from FirebaseDatabase. During the debugging on my watch list i get value of the snapshot as null. I need to get city name of the current user from db.
void addToFb() async {
final User user = FirebaseAuth.instance.currentUser;
final uid = user.uid;
final city = await FirebaseDatabase.instance
.reference()
.child('Users')
.equalTo(uid)
.once()
.then((DataSnapshot snapshot) {
var temp = snapshot.value.city;
return temp;
});
Just in case my database looks like this:
- Users
|- uid
||- name
...
||- city
Thanks in advance!
This is not the solution but for make your code and db structure easy,
I suggest you to use Cloud Firestore
Because you can find all types of queries in this.
Cloud Firestore dependency
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'];
}