Firebase and Kotlin: getting the id of a document issues - firebase

I have an interesting issue while playing with Firebase and Kotlin.
val docRef = db.collection("Year")
.document(DB_year.toString())
.collection("Month")
.document((DB_month+1).toString())
.collection("Day")
.document(today)
.collection("write")
.get()
.addOnSuccessListener { result ->
for(document in result) {
println("document_id : " + document.id)
}
}
If you get the document id with this code, you can get it normally.
enter image description here
enter code here
This code cannot get the document id.
val docRef = db.collection("Year")
.document(DB_year.toString())
.collection("Month")
.document((DB_month+1).toString())
.collection("Day")
.get()
Why is it like this?
my firestore collection
enter image description here
enter image description here

As shown in your Firebase console screenshot above, the documents in the Day collection are displayed with an italic font in the Firebase console: This is because these documents are only present (in the console) as "container" of one or more sub-collection but are not genuine documents.
If you create a document directly under the write collection with the full path Year/docYear1/Month/subDocMonth1/Day/subDcoDay1/write/writeDoc, no intermediate documents will be created (i.e. no document in the Month or Day collections).
The Firebase console shows this kind of "container" (or "placeholder") in italic in order to "materialize" the hierarchy and allow you to navigate to the write document but the Day document doesn't exist in the Firestore database. Hence the empty result for your second query
See this answer for more details.
Note that if you want to get the parent ids (docs and collections) for a doc in the write collection, you can use the parent properties of the DocumentReference and CollectionReference.
So you can do something like:
db.collection("Year")
.document(DB_year.toString())
.collection("Month")
.document((DB_month+1).toString())
.collection("Day")
.document(today)
.collection("write")
.get()
.addOnSuccessListener { result ->
for(document in result) {
println("Day_doc_id : " + document.reference.parent.parent?.id)
}
}

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.

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

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!

Update Firebase Array using.where(). But, getting error ".update isn't a function

So, I am trying to update a document in my firebase that has an array.
Currently, a users document may look like this.
username : John
postedProjects : ['project-one','project-two']
However, as John submits "project-three" to another collection, I want to grab johns document, and add "project-three" into his array.
Here is my code currently (Please note, I am not using the document
UID as I have set UID as name, but the user may change their username
down the line, but their UID remains the same)
var newProject = db.collection('users').where('user_id', '==', this.userInfo.user_id);
newProject.update({
postedProjects: firebase.firestore.FieldValue.arrayUnion("test")
})
This is the code I have followed from the Firebase doc, with the slight adjustment of changing .doc(uid) to .where, to instead match the existing user to the one on the collection.
However, I get an error stating "newProject.update is not a function".
-- Added .where but still getting error as i am not sure where to put the "update()"
db.collection('users').where('user_id', '==', this.userInfo.user_id)
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
doc.data().update({
postedProjects: firebase.firestore.FieldValue.arrayUnion("new project")
})
})
})}}
where() returns a Query object, which doesn't have an update() method, as you can see from the linked API documentation. Since there is no guarantee how many documents could result from executing a query, you will have to get() the query, then iterate the results to find a DocumentSnapshot that matches document, use its ref property to get a DocumentReference for it, and finally update() the document using that DocumentReference.

Create documents, sub collections in Firestore via flutter on screen loads

I want to achieve is when flutter screen loads a document should create in firestore in following order.
Document > Sub Collection > Document > Data Fields
I manage to create documents and sub collections in above order, but the first Document appear in italic. That's because the child collection, documents creating before parent document created.
But I couldn't able to fix the issue. I've modified the code now it's not even creating the document. Before this It created in italic mode. Now it's not at all.
Here is the code.
getCurrentUser().then((user) {
DocumentReference todayReference = firestoreInstance.collection('attendance').document(todayDate);
firestoreInstance.collection('profiles').where('user_id', isEqualTo: user).snapshots().listen((onData) {
onData.documents.forEach((f) {
CollectionReference todaySubCollection = todayReference.collection(f.documentID);
DocumentReference attendanceReference = todaySubCollection.document(f["name"].toString().toLowerCase());
Map<String,dynamic> mapData = new Map<String,dynamic>();
mapData['attendance_status'] = true;
mapData['in'] = true;
mapData['out'] = true;
firestoreInstance.runTransaction((transaction) async {
await transaction.set(attendanceReference, mapData);
});
});
});
});
Here getCurrentUser() is returning the logged in user id.
Each profiles assigned to a user.
So, What I'm trying to do is, once user logged in a document should create under attendance collection named today's date.
Then looping through each profiles where user_id is matched with logged in user, the matching results will be store as sub collection under today's date with profiles name field.
Then under the name (document), a transaction needs to run to set details like attendance_status, in & out.
Following images will show how previously documents created.
I need to find a way to create documents, collection without in italic mode. Any help would be appreciated.
"Italicized" documents are virtual/non-existent as mentioned in the docs. If a document only has a sub-collection, it will be a virtual/non-existent document. A workaround for this is by writing fields in the document, like what you've mentioned in the comments.

Resources