We have a complex JSON having multiple sub-objects inside main object.
For example:
dept: {
name: Dept1,
emps: [
{
empCode: 001,
empName: Emp001
}
]
}
If we use db.collection("dept").add(deptPojo) then it auto creates "emps" subcollection and auto assigns document id for each emp object.
But we want empCode to be assigned as document id for each emp document.
Is this achievable? How? Is there any #Id annotation in firebase firestore api?
Updated
Now you can do it using #DocumentId from firebase.Just add it in your POJO class
There is currently no way to indicate the ID using an annotation, but I believe the Firebase team is looking into a solution for that.
Sorry guys, my bad!
I was under impression that array of emps inside dept in my example above will end up with creating sub-collection emps having each entry in an array an auto-generated document id.
But later I understood that, I was wrong in this assumption.
The behavior is as follows.
If you have nested objects (i.e. parent having a field of type List or Map.
Then they are stored as an array in firestore instead of creating a dedicated sub-collection.
Means in case of saving pojo object, firebase doe's not auto create sub-collections.
As show in screenshot here... devices is a Map of device objects but it stored as array.
Thanks.
Related
In my firebase db I have 3 collections:
Users
{user_id}: {name: "John Smith"}
Items
{item_id}: {value: 12345}
Actions
{action_id}: {action: "example", user: {user_id}, items:{item_id}}
Basically, instead of storing the Users and Items under the Actions Collection, I just keep an ID. But now I need a list of all actions and this also needs info from the Users and Items Collection. How can I efficiently query firebase so I can get a result that looks like this:
{
action: "example",
user: {
name: "John Smith"
},
item: {
value: 1234
}
}
Unfortunately, there is no such thing in firebase or a similar database, basically, you are looking for a traditional join, which is no recommended thing to do in a NoSQL database.
If you want to do it in firebase, you will need:
Get the element you are looking for from your main collection Actions in this case.
Then you need to do another call to the Items collections where item_id == action.item_id.
Then assign in the actions["Item"] = item_gotten.
This is not a recommended use as I said, usually, when you are using a NoSQL Database you are expecting a denormalize structure, from your application you need to save the whole Item, in the Action JSON, and also in the Item. Yes, you will have duplicate data but this is fine for this kind of model. also you shouldn't expect too many changes in one specific object within your whole object key If you are managing a big set of changes you could be using the incorrect kind of DB.
For aggregation queries reference, you might check: https://firebase.google.com/docs/firestore/solutions/aggregation
im working on firebase and im trying to update the document name and its field name together like shown in the image. i want them to be updated together.
i used this code
EditCourse(String cName, String newName) async {
var collection = FirebaseFirestore.instance.collection("Courses")
..where("Course name", isEqualTo: cName);
collection.doc(cName).update({'Course name': newName});
}
Answer:
As of Now Firebase not allows to update documents ids)
Suggestion:
You should use relational ids or random ids
(relational ids means suppose you have seller favorite collection you can give documents ids to movie/food ids)
There is no way to update the document ID of an existing document. If changing course names is a use-case you need to support, consider using Firestore's built-in ID generation when adding your documents (so add documents using the add() method).
If you stick to your current model, you'll have to:
Read the existing document.
Write the date under the new ID.
Delete the original document.
Given the type of operation, you'll probably want to use a transaction for that.
I have a collection "Tasks" that include some fields : The user that added the task, the name of the task, the category and I want to add another one with the steps of the task. Do I have an option to add a "Steps" field (and not collection!), and in this field I will have all the steps of the task?
Here the image of my firestore structure : Firestore structure
Of course, just use update
collection('Tasks').doc(docId).update({"steps" : "yourSteps"})
yourSteps here can be a string, int, list, a whole new map, anything. Without affecting the other fields in your document like category.
Important note:
.set() can also merge new data into the existing document if you pass the merge options:
.set(data, {merge: true})
.set() will write to the document if it exists, and will create a new document if it does NOT exist - with the mergeOption, it can merge in new fields or update selected ones.
.update() is similar, BUT if the document does not exist .update() will FAIL..
https://firebase.google.com/docs/reference/js/firebase.firestore.DocumentReference#set
Here is the schema for test db:
I want to write a query that can get all the documents where contacts have id=1 in any of the array index.
I have checked array_contains operator for firestore but the thing is my array have map which then have field id.
Thanks
You currently can't build a query that looks for an object field within an array. The only things you can find in an array are the entire contents of an array element, not a part of an element.
With NoSQL type databases, the usual practice is to structure you data in a way that suits your queries. So, in your case, you're going to have to structure your data to let you find documents where an array item contains a certain string. So, you could create another array that contains just the strings you want to query for. You will have make sure to keep these arrays up to date.
You could also reconsider the use of an array here. Arrays are good for positional data, but unless these contacts need to be stored in a certain order, you might want to instead store an object whose keys are the id, and whose field data also contains the id and name.
As Doug said, you can't query it,
but, if you could structure your data to something that looks like this
Store your data as a map
Use id as key and name as value
Now you can write a query that can get all the documents where contacts have id=1
db.collection("test").where("contacts.1", ">=", "").get()
If you have an array of maps or objects and want to get the docoments that contains this specific map/object like this ?
array_of_maps.png
you can use
queryForCategory(categName: string, categAlias: string): Observable[] {
firestore.collection('<Collection name>', ref =>
ref.where('categories',
"array-contains", {
"alias": categAlias,
"title": categName
}
One soulions is as #Doug said, to add array with the data you need to query, and keep it uptodate.
Another solution is to make contacts as sub collection of the document, an then you could make queries of the contacts and get its parrent.
final Query contacts = db.collectionGroup("contacts").whereEqualTo("id", 1);
for (DocumentSnapshot document : querySnapshot.get().getDocuments()) {
System.out.println(document.getId());
System.out.println(document.getString("parent_id"));
}
If you don't want to add parent as another field, you can get it from parent reference, check this answer https://stackoverflow.com/a/56223319/1278463
snapshot.getRef().getParent().getParent().collection("people")
https://firebase.google.com/docs/firestore/query-data/queries#collection-group-query
Please I want to give custom IDs to my database objects in Firebase but I don't now how to do it. Firebase creates default IDs for database objects which I don't want. I want to be able to assign my own IDs to objects or the child nodes of in the database for unique identification.
Most likely you're adding the items to the database with something like:
ref.push().set("my value");
This generates a new unique key under ref and sets your value on it.
If you want to use you own key/name for the child location, add the item with:
ref.child("my key").set("my value");
You cannot customize ID of firebase object, but you can create another field with ID role.
ref.child("my_id").set("customize_id");
after that, using "Filter by key" to get exactly your object you want.
In our case: We need to have a user_id type Int and auto-increase, so we can't use default _id of firebase object, we create user_id ourself to solve this problem.