Retrieve field information form Firestore database - firebase

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.

Related

How can I update value of the field of the document by userID Field without doc ID in the Firebase collection in flutter?

I want to update value of the field's document. I wrote a query but it doesn't work.
**//this query is working, I hava a doc Id**
final CollectionReference _company = FirebaseFirestore.instance
.collection('Company')
..where(FieldPath.documentId, isEqualTo: _auth.currentUser!.uid);
**// But this query is not working, because I have not doc** ID, its doc ID auto gen. ID in firebase
final CollectionReference _companyAdvert =
FirebaseFirestore.instance.collection('CompanyAdvert')..where('userId', isEqualTo: _auth.currentUser!.uid) ;
all the code here
To update a document field in firestore, you need to write
await FirebaseFirestore.instance
.collection('CompanyAdvert')
.doc(id)
.update({ 'profileImage': *new profile image* });
You must understand that to update a firestore document, you must keep a reference of the document id in the document itself. You can think of this as the primary key for the document.
There are two ways to do this.
1. Get a reference to the newly created document, and then get the id from the reference.
Then update the document with this id
2. Generate a random id locally and use that as the document id.
You can do this with the [Uuid package][1] on pub.dev
The first step goes like this:
// first, create a document using the add method
DocumentReference docRef = await FirebaseFirestore.instance
.collection('CompanyAdvert')
.add(*data*);
// then extract the generated document id
String id = docRef.id;
// then save it back to the document using
await FirebaseFirestore.instance
.collection('CompanyAdvert')
.doc(id)
.update({'id': id});
The second step goes like this:
String id = const Uuid().v4();
await FirebaseFirestore.instance.collection('CompanyAdvert').doc(id).set(*data*);
// Make sure you add the id as one of the fields to the map data
Note that the first step incurs a write operation which will count against your total quota for firebase. I recommend you use the second approach
Visit the FlutterFire documentation to learn more

Flutter Firestore - How to get data from a Document Reference in a Document Field?

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 CRUD the value of the FireStore in the method

・ What I want to do.
I have stored the document ID of the currently accessed room in user collection>document>field>documentID.
I want to retrieve it and rewrite the document in the room collection.
But I can't rewrite it.
I want to know how to get the data and rewrite it.
[The document ID in the user collection is the user ID.]
I want to retrieve the field in the following method
void _onConferenceTerminated(message) async {
//[Image 1] I get the documentID being accessed from the documentID in the field of the user collection
final user = FirebaseFirestore.instance.collection('user').doc(uid()).get();
final getDocId = user.data['documentID']
//[*image2]Use it to access the room document and reduce the roomCount
final setRoomCount = await FirebaseFirestore.instance.
.collection('room')
.doc(getDocId)
.set({'roomCount': roomCount - 1});
}
//Get the user ID
String uid() {
final User user = FirebaseAuth.instance.currentUser!
final String uid = user.uid.toString();
return uid
[image1]
[image2]
You could use .update() instead of .set() if you want to change only one field. I also recommend you to use FieldValue.increment(value) which is built-in function in firestore.
Value could be both int and double.
FieldValue.increment(1)
FieldValue.increment(2.0)
Also, you can use negative numbers to decrease the value. In your case, you can try the below code.
await FirebaseFirestore.instance
.collection("room")
.doc(getDocId)
.update({"roomCount": FieldValue.increment(-1)}
Documentation: https://firebase.google.com/docs/firestore/manage-data/add-data#increment_a_numeric_value

Flutter: How to retrieve all the Firebase user data from its uid?

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);
});
});

Fetch collection startAfter documentID

Is there a way to fetch document after documentID like
private fun fetchCollectoionnAfterDocumentID(limit :Long){
val db = FirebaseFirestore.getInstance()
var query:Query = db.collection("questionCollection")
.startAfter("cDxXGLHlP56xnAp4RmE5") //
.orderBy("questionID", Query.Direction.DESCENDING)
.limit(limit)
query.get().addOnSuccessListener {
var questions = it.toObjects(QuestionBO::class.java)
questions.size
}
}
I want to fetch sorted questions after a given Document ID. I know I can do it using DocumentSnapShot. In order to fetch the second time or after the app is resume I have to save this DocumentSnapshot in Preference.
Can It be possible to fetch after document ID?
startAfter - > cDxXGLHlP56xnAp4RmE5
Edit
I know I can do it using lastVisible DocumentSnapshot . But I have to save lastVisible DocumentSnapshot in sharedPreference.
When app launch first time 10 question are fetched from questionCollection. Next time 10 more question have to be fetched after those lastVisible. So for fetching next 10 I have to save DocumentSnapshot object in sharedPreference. Suggest me a better approach after seeing my database structure.
And one more thing questionID is same as Document reference ID.
There is no way you can pass only the document id to the startAfter() method and simply start from that particular id, you should pass a DocumentSnapshots object, as explained in the official documentation regarding Firestore pagination:
Use the last document in a batch as the start of a cursor for the next batch.
first.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
=// Get the last visible document
DocumentSnapshot lastVisible = documentSnapshots.getDocuments()
.get(documentSnapshots.size() -1);
// Construct a new query starting at this document,
Query next = db.collection("cities")
.orderBy("population")
.startAfter(lastVisible) //Pass the DocumentSnapshot object
.limit(25);
// Use the query for pagination
}
});
See, here the lastVisible is a DocumentSnapshot object which represents the last visible object. You cannot pass only a document id. For more information, you can check my answer from the following post:
How to paginate Firestore with Android?
It's in Java but I'm confident you can understand it and write it in Kotlin.
Edit:
Please consider defining an order of your results so that all your pages of data can exist in a predictable way. So you need to either specify a startAt()/startAfter() value to indicate where in the ordering to begin receiving ordered documents or use a DocumentSnapshot to indicate the next document to receive, as explained above.
Another solution might be to put the document id into the document itself (as a value of a property) and order on it, or you can use FieldPath.documentId() to order by the id without having to add one.
You can also check this and this out.
There is one way to let startAfter(documentID) works.
Making one more document "get", then using the result as startAfter input.
val db = FirebaseFirestore.getInstance()
// I use javascript await / async here
val afterDoc = await db.collection("questionCollection").doc("cDxXGLHlP56xnAp4RmE5").get();
var query:Query = db.collection("questionCollection")
.startAfter(afterDoc)
.orderBy("questionID", Query.Direction.DESCENDING)
.limit(limit)
A simple way to think of this: if you order on questionID you'll need to know at least the value of questionID of the document to start after. You'll often also want to know the key, to disambiguate between documents with the same values. But since it sounds like your questionID values are unique within this collection, that might not be needed here.
But just knowing the key isn't enough, as that would require Firestore to scan its entire index to find that document. Such an index scan would break the performance guarantees of Firestore, which is why it requires you to give you the information it needs to perform a direct lookup in the index.

Resources