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

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

Related

Retrieve field information form Firestore database

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.

Flutter and Firebase - Get Specific Documents From Firebase

When you go into posts collection there are documents based on userId. And inside a document there is a new collection named userPosts. Inside userposts you can find postId and the details about the post.
I can get specific user post by using this code
postRef = Firestore.instance.collection('posts');
QuerySnapshot snapshot = await postRef
.document(userId)
.collection('userPosts')
.getDocuments();
But I want to get all the user posts without naming a specific user. How could I achieve this?
You can use a collection group query to query documents among all collections with same name.
QuerySnapshot snapshot = await Firestore.instance
.collectionGroup('userPosts')
.getDocuments();

Firebase Firstore subcollection

please how can I get all the value of my IndividualTaxData subcollection in Flutter.
First, you must get the reference to the parent document:
DocumentReference parentRef = Firestore.intances.collection('TaxData').document(taxDataId);
You can do the previous part with a direct reference to the document (like the code above) or with a query. Later, you must get the reference of the subcollection and the document that you get the information:
DocumentReference subRef = parentRef.collection('IndividualTaxData').document(individualTaxId);
And finally, get the data:
DocumentSnapshot docSnap = await subRef.get();
For you to return a simple document, you can use the following code for it.
var document = await Firestore.instance.collection('IndividualTaxData').document('<document_name>');
document.get() => then(function(document) {
print(document('character'));
// you can print other fields from your document
}
With the above code, you will reference your collection IndividualTaxData and then load it's data to a variable that you can print the values.
In case you want to retrieve all the documents from your collection, you can start using the below code.
final QuerySnapshot result = await Firestore.instance.collection('IndividualTaxData').getDocuments();
final List<DocumentSnapshot> documents = result.documents;
documents.forEach((data) => print(data));
// This print is just an example of it.
With this, you will load all your documents into a list that you iterate and print after - or that you can use with another method.
In addition to that, as future references, I would recommend you to check the following links as well.
Query a single document from Firestore in Flutter (cloud_firestore Plugin)
How to use Cloud Firestore with Flutter
Le me know if the information helped you!

is it correct or safe to manualy set the document value of collections in Firebase?

by default the document value of collections is generated automatically, how about if we set that manually during insertion? is it safe and a right way?
example:
await _firestore.collection('collectionName').document(manualID).setData({...});
by this way, I think it is easy to retrieve a specific document from a collection.
You can either add your own id or you can let firebase generate the id. If you can be sure that each document you will create under the collection will have a different id, then there will be no problem if you add your own implementation.
Firebase generating an id:
final firestoreInstance = Firestore.instance;
await firestoreInstance.collection("users").add({});
Adding your own id:
final firestoreInstance = Firestore.instance;
await firestoreInstance.collection("collectionName").document(id).setData({});

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