Put only existing subcollection in a list firebase(flutter) - firebase

I've been trying to put document snapshots of a sub-collection in a list. The code for it is something like this:-
getcoffeebuyerlist() async {
DocumentSnapshot coffeebuyers;
List<DocumentSnapshot> finalCoffeBuyerList = [];
for (var i = 0; i < profiles.length; i++) {
coffeebuyers = await Firestore.instance
.collection('profileData')
.document(profiles[i].uid)
.collection('coffeeprices')
.document(profiles[i].uid)
.get();
finalCoffeBuyerList.add(coffeebuyers);
}
return finalCoffeBuyerList;
}
There are two profile and only one of which has a sub-collection 'coffeeprices'.
My doubt here is by trying get snapshot of sub-collections, will I automatically be creating an empty document for the second profile for which sub-collection doesn't exist and put in finalCoffeBuyerList list?
Or only those(one in my case) sub-collection which already exist are added to this list?

Your code here will never create any documents. get() doesn't create a document if the document doesn't already exist. You should check the returned DocumentSnapshot to see if the document actually exists. Something like this:
if (coffeebuyers.exists) {
finalCoffeBuyerList.add(coffeebuyers);
}
The only way to create a document is with add() or set().

Related

Get data from subcollection in firestore flutter

In the 1st screen shot there are many documents in collection users. Each documents contains further collection jobPost and that collection contains further documents and its meta data.
What I want here is go to the every document of collection users and further subcollection jobPost and fetch all the documents.
Suppose first it should go to document 1 in collection users, in the document 1 it should fetch all the documnets in subcollection jobPost then it should go to the 2nd document of collection users and then get all the documents in the subcollection jobPost and so on. what will be the query or implementation to this technique
What you're describing is known as a collection group query, which allows you to query all collections with a specific name. Unlike what the name suggests, you can actually read all documents from all subcollections named jobPost that way with:
FirebaseFirestore.instance.collectionGroup('jobPost').get()...
When performing a query, Firestore returns either a QuerySnapshot or a DocumentSnapshot.
A QuerySnapshot is returned from a collection query and allows you to inspect the collection.
To access the documents within a QuerySnapshot, call the docs property, which returns a List containing DocumentSnapshot classes.
But subcollection data are not included in document snapshots because Firestore queries are shallow. You have to make a new query using the subcollection name to get subcollection data.
FirebaseFirestore.instance
.collection('users')
.get()
.then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
FirebaseFirestore.instance
.document(doc.id)
.collection("jobPost")
.get()
.then(...);
});
});
**
if you not have field in first collection document then its shows italic thats means its delte by default otherwise if you have field in first collection document then you can access it easily so this is the best way that i share
**
static Future<List<PostSrc>> getAllFeedPosts()async
{
List<PostSrc> allPosts = [];
var query= await FirebaseFirestore.instance.collection("posts").get();
for(var userdoc in query.docs)
{
QuerySnapshot feed = await FirebaseFirestore.instance.collection("posts")
.doc(userdoc.id).collection("userPosts").get();
for (var postDoc in feed.docs ) {
PostSrc post = PostSrc.fromDoc(postDoc);
allPosts.add(post);
}
}
return allPosts;
}

How to read firestore collection?

How can I list all documents in a firestore
FirebaseFirestore.instance
.collection('groups')
.doc('dialog')
.get()
.then((DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists) {
print('Document data: ${documentSnapshot.data()}');
} else {
print('Document does not exist on the database');
}
});
this code Always return to else
From the docs:
When you delete a document, Cloud Firestore does not automatically delete the documents within its subcollections. You can still access the subcollection documents by reference. For example, you can access the document at path /mycoll/mydoc/mysubcoll/mysubdoc even if you delete the ancestor document at /mycoll/mydoc.
Non-existent ancestor documents appear in the console, but they do not appear in query results and snapshots.
A document can exist even if one or more its ancestors don't exist. For example, the document at path /mycoll/mydoc/mysubcoll/mysubdoc can exist even if the ancestor document /mycoll/mydoc does not. The Cloud Firestore data viewer displays non-existent ancestor document as follows:
In a collection's list of documents, the document IDs of non-existent ancestor documents are italicized.
In a non-existent ancestor document's information panel, the data viewer points out that the document does not exist.
Since your document name is italicized, which means you either deleted the document or added the subcollection to an empty document which it seems you might have done according to your screenshot. Therefore to solve the issue delete the collection group and add the document with data:
FirebaseFirestore db = FirebaseFirestore.instance;
db.collection("group").doc("dialog").set({"name" : "peter"}).then((value){
db.collection("group").doc("dialog").collection("Tkxij").add({"test" :"test"});
});
Also queries are shallow, meaning if you are referencing a document then you will only get the data of that document, you won't get the data inside the subcollections.
I have added the code for your problem hope this clears your doubt, feel free to ask if you have any doubt.
getData( ) async{
final collectionData = await FirebaseFirestore.instance
.collection('groups').get();
//this forEach method will give every document of that collection
collectionData.docs.forEach((doc) {
final docData = doc.data();
final fieldData = docData['fieldName'];
});
}

How to search list of queries and combine them to a single query?

I am working on a social networking app whose data model is as follows:
Here posts collection contains multiple documents with same or different tag fields, a user can follow multiple tags I already have those tags in a list I need to extract the documents where tag is equal to an element of that list and sort them according to time stamp
getPosts() async {
for (int i = 0; i < Constants.hashtags.length; i++) {
QuerySnapshot dataDoc = await Firestore.instance
.collection("posts")
.where("tag", isEqualTo: Constants.hashtags[i])
.getDocuments();
}
}
Here Constants.hashtags is list of tags that a user if following. I am able to get all documents using above code but I don't know how to merge these documents in a single and sorted way which can be further presented to user in a List.builder form.
Looking at the documentation Here,
you can see the where has an optional parameter whereIn
Query where (
dynamic field,
{dynamic isEqualTo,
dynamic isLessThan,
dynamic isLessThanOrEqualTo,
dynamic isGreaterThan,
dynamic isGreaterThanOrEqualTo,
dynamic arrayContains,
List arrayContainsAny,
List whereIn,
bool isNull}
)
And you can use it Like
QuerySnapshot dataDoc = await Firestore.instance
.collection("posts")
.where("tag", whereIn: Constants.hashtags)
.getDocuments()
This query snapshot contains list of all documents that has a tag field which is equals to Constants.hashtags

how to retrieve unknown sub collection from document in flutter

I have the following code with the objective of retring all the documents like this: Collection('A').document(currentUser), this should give me the document YRZ1**** as you may see in the first image. Now what I want to do is get all the documents in the t22o9*** subcollection, as showned on the second image, how can I do that?
var docPath=Firestore.instance.document('Messages/$currentUser');
docPath.snapshots().listen((event) {
print('Hello 12 ${event.data}');
});
In order to get data from subcollection you can do the following:
var db = Firestore.instance;
//This is a reference to the YRZ1**** doc
var messagesDoc = db.collection('Messages').document('Messages/$currentUser');
//collectionId is the t22o9*** id, you need to have this set previosly in your code
var docList = [];
messagesDoc.collection(collectionId)
.getDocuments()
.then((QuerySnapshot snapshot) {
snapshot.documents.forEach((doc) => docList.add(doc)'));
});
With this code, docList will be a list of the documents located at your subcollection t22o9*** of the YRZ1*** document.
Also you can check this link with some examples on how to get data from firestore using flutter.
EDIT:
As per what you have clarified on the comments, getting the subcollection data is a bit more complicated with subcollections that were created dynamically, as you can see on this link, which I assume is the case you have. The most feasible solution in your case would be to create a list of ids of subcollections in your parent document, so for example your YRZ1*** document would have this structure
document
id: YRZ1***
subCollectionIds : [subCollectionId1, subCollectionId2,...]
subCollection1
subCollection2
...
subCollectionN
Having this structure you could use this code to retrieve the list of subcollections and the first document of each subcollection, ordered by whatever field you'd like:
var db = Firestore.instance;
var listFirstDocSub = []
//This is a reference to the YRZ1**** doc
db.collection('Messages')
.document('Messages/$currentUser')
.getDocument()
.then((DocumentSnapshot doc) {
var listSubCollections = doc["subCollectionIds"];
listSubCollections.forEach((id) {
db.collection('Messages')
.document('Messages/$currentUser')
.collection(id)
.orderBy("WHATEVER_FIELD_YOU_DECIDE")
.limit(1)
.getDocuments()
.then((DocumentSnapshot snapshot) {
listFirstDocSub.add(snapshot);
})
});
});
NOTE: With this approach, everytime you add a new subcollection, you will also need to add it's id to the subCollectionIds list.
Hope This helps.

how do I check collection exists or not in firestore on flutter?

I get some data from firestore. Sometimes when I called to get data, the collection is not created yet.
before calling get request, how do I check collection is exists or not?
Stream<List<ChatModel>> getChat(ChatFieldModel model) {
var ref = _db.collection('chats');
return ref
.document(model.docId)
.collection('messages')
.orderBy('timestamp', descending: true)
.snapshots()
.map((list) =>
list.documents.map((doc)=>ChatModel.fromForestore(doc)).toList());
}
I posted this before
final snapshot = await firestore.collection(roomName).getDocuments();
if (snapshot.documents.length == 0) {
//doesnt exist
}
Hope this helps
Collections are not created or deleted independently of documents. When you create a document and specify it as being part of a certain collection, that collection is created automatically if it does not already exist. Similarly, when you remove the last document in a collection, that collection will automatically be deleted. So there is really no circumstance where you need to worry about whether a collection has been created or not, and you have no explicit control over creating or deleting collections.
Usually a collection in Firestore gets deleted if no Documents exist in it.
However, there might be cases where you want to keep a history of the collection modification events, or let's say for some reason prevent Collections from being deleted.
Or for example, you want to know when a collection was created in the first place. Normally, if the Documents are deleted, and then the Collection gets created again, you will not know the initial creation date.
A workaround I can think of is the following:
Initialize each collection you want with a Document that will be specifically for keeping generic info about that collection.
For example:
This way, even if all other Documents in the Collection are deleted, you'll still keep the Collection in addition to some info that might be handy if In the future you need to get some history info about the Collection.
So to know if a Collection exists of no, you can run a query that checks for a field in Info Documents (eg CollectionInfo.exists) to know which Collections have been already created.
This is for the most recent update
final snapshot = await FirebaseFirestore.instance
.collection('collection name').get();
if ( snapshot.size == 0 ) {
print('it does not exist');
}
Feb 2022
Get QuerySnapshot and return querySnapshot.docs.isNotEmpty or isEmpty
Future<bool> isItems() async {
CollectionReference collectionReference =
_firestore.collection("users").doc(_user!.uid).collection("cart");
QuerySnapshot querySnapshot = await collectionReference.get();
return querySnapshot.docs.isNotEmpty;
}
await FirebaseFirestore.instance
.collection('collectionName')
.limit(1)
.get()
.then((snapshot) {
if (snapshot.size == 0) {
print("No collection");
}
});

Resources