My database looks something like this:
Now as I start adding more and more data I will be getting variety of users. I want to extract data from one user based on their user ID. I tried using these codes but none of them worked. I am getting data in bulk of all the users but I just want one of them. Here's my attempt:
final data=await _collection.collection('UserDetails').getDocuments();
//print(user.uid);
DocumentReference ref = await _collection.collection('UserDetails').document(user.uid);
var lister=await ref.collection('Name');
print(lister);
This is the code for getting all their data:
for(var msgs in data.documents)
{
print(msgs.data);
}
I want a function or anything which could return data in this way:
function.giveUserID('uid').giveDataYouwanttoExtract('Attribute')
I can filter out using string conditions from all the data I am getting but as the database rises it will have to extract tons of data at once which will affect the performance and so I want to do this in this way. Please let me know if there's any way to just extract data of one user based on their uid or email or anything.
You can use queries. The code below returns all the users where name is equals to the Jack.
await _db.collection("UserDetails")
.where("Name", isEqualTo: "Jack")
.getDocuments()
.then((QuerySnapshot snapshot){
snapshot.documents.forEach((DocumentSnapshot documentSnapshot){
print(documentSnapshot.data);
});
});
Related
I'm building a Self-learning app with differente questions types. Right now, one of the questions have a field containing a list of DocumentReferences:
In Flutter, I have the following code:
Query<Map<String, dynamic>> questionsRef = firestore
.collection('questions')
.where('lesson_id', isEqualTo: lessonId);
await questionsRef.get().then((snapshot) {
snapshot.docs.forEach((document) {
var questionTemp;
switch (document.data()['question_type']) {
....
case 'cards':
questionTemp = CardsQuestionModel.fromJson(document.data());
break;
....
}
questionTemp.id = document.id;
questions.add(questionTemp);
});
});
Now, with "questionTemp" I can access all the fields (lesson_id,options,question_type, etc..), but when it comes to the "cards" field, how Can I access the data from that document reference?
Is there a way to tell firestore.instance to get the data from those references automatically? Or do I need to make a new call for each one? and, if so, how can I do that?
Thank you for your support in advance!
Is there a way to tell firestore.instance to get the data from those
references automatically? Or do I need to make a new call for each
one?
No there isn't any way to get these documents automatically. You need to build, for each array element, the corresponding DocumentReference and fetch the document.
To build the reference, use the doc() method
DocumentReference docRef = FirebaseFirestore.instance.doc("cards/WzU...");
and then use the get() method on this DocumentReference.
docRef
.get()
.then((DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists) {
print('Document exists on the database');
}
});
Concretely, you can loop over the cards Array and pass all the Futures returned by the get() method to the wait() method which "waits for multiple futures to complete and collects their results". See this SO answer for more details and also note that "the value of the returned future will be a list of all the values that were produced in the order that the futures are provided by iterating futures."
I want to get data from firebase only if the user is not saved in the document. Because I need a or-query, which is not possible in Firebase, I decided to use RxDart's CombinedStreams with two steams:
var streamOne = FirebaseFirestore.instance
.collection('jobs')
.where('jobState', isEqualTo: 1)
.where('userOne', isNotEqualTo: FirebaseAuth.instance.currentUser!.uid)
.snapshots();
var streamTwo = FirebaseFirestore.instance
.collection('jobs')
.where('jobState', isEqualTo: 1)
.where('userTwo', isNotEqualTo: FirebaseAuth.instance.currentUser!.uid)
.snapshots();
But my app shows the data even if the current user is in 'userOne' OR 'userTwo'. Is it possible to avoid this and get the data just if the currentUser is not 'userOne' OR 'userTwo'?
Your logic is flawed: if the UID is in userOne, the second query will still return that document, and vice versa. What you want is actually an AND: the documents where the UID is not in userOne and not in userTwo.
Unfortunately though that query also isn't possible on Firestore, as all not-equal conditions in a query must be on the same field.
There is no way to capture your logic in a single query, and you will have to filter the documents fo userOne and userTwo in your application code instead.
So I want to retrieve name of a user which is inside a field in firestore.
The whole sequence in given in image below.
I want to get the string value 'a' which is inside (chatroom->a_qaz->users->'a').
I am trying to get it with this code but its not working. How to get the field information.
getOtherUserByUsername() async {
return await FirebaseFirestore.instance
.collection("chatroom")
.doc("chatRoomId")
.get();
First of all, let's get the document from your collection.
collection.doc(), as per reference, gets the actual ID as parameter. In your case, you need to specify "a_qaz". After that, you get the document and then you can read the fields. Your code should look like this:
let chatRoom = await FirebaseFirestore.instance
.collection("chatroom")
.doc("a_qaz")
.get();
let users = chatRoom.get("users");
users will store, then, the list of users that's in that field.
I am trying to retrieve data of all the users of the users collection and compare it with some other data. I am able to retrieve data of a particular user from its uid but want to iterate through all the collections and documents.
If you don't specify a specific document ID and use the get() method on a CollectionReference, it'll return a QuerySnapshot (containing all documents in that collection) which essentially is an array of QueryDocumentSnapshot.
FirebaseFirestore.instance
.collection('users')
.get()
.then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
print(doc["field_name"]);
});
});
You can use "QuerySnapshot" to retrieve data of all the users of the users collection. Please see an example of same at https://firebase.flutter.dev/docs/firestore/usage/#document--query-snapshots
I expect you are currently using "DocumentSnapshot" to retrieve data of a particular user.
I'm currently building a social network app using Firebase and Flutter, and I've stumbled onto a bit of a problem. My homepage has two tabs, one that contains all posts on the app in chronological order, and the other that contains the posts of the people you follow. The DocReferences of the people the user follows is inside a list. Currently, the code looks like this:
if (myFollows.isNotEmpty)
for (int j = 0; j < myFollows.length; j++) {
await FirebaseFirestore.instance
.collection('posts')
.orderBy('date', descending: true)
.where('user', isEqualTo: myFollows[j])
.get()
.then((value) {
//code
});
But, as you can see, I create seperate queries for each of the followed users, so the resulted list of posts isn't in chronological order.
So, my question is, if there is a way I could query the post documents where the user variable is contained inside the list myFollows, instead of comparing it to each of its values one by one?
Remove the loop and use whereIn. This should work
if (myFollows.isNotEmpty)
await FirebaseFirestore.instance
.collection('posts')
.orderBy('date', descending: true)
.where('user', whereIn: myFollows) //this line changed
.get()
.then((value) {
//code
);
In your 1st execution, you may need to add a new index... just follow the web link (in error message) that will help create this required index.
May not work if following more than 10 users as this is a built-in limit in Firestore (maximum 10 comparisons).
In that case, there is no built-in solution... you need to keep your loop and append every single query separately... then sort your final list.