I am trying to figure out how i would go about removing and adding to the profile array in the array of objects. I have the id's to get to the appropriate items in the arrays but it looks like i can only update the entire root array item.
doc().update({
technologyLearned: firebase.firestore.FieldValue.arrayRemove("?")
});
if this was a normal language i could technologyLearned[id].profiles[profileid] and get to the item i need to remove or add.
Since you can't index into an array to locate an item to remove, you will have to read the entire document, modify the array in memory, then write it back to the document.
The problem here is that technologiesLearned is an array (not that profiles is an array). If profiles was not nested under technologiesLearned array, you could use arrayRemove on it.
Related
im trying to make a sort of chat app with the following architecture:
Its currently working as follows: in a root doc, there is an array of chat objects. Each chat object spawns a message doc, which contains an array of message objects. Same logic for comments.
Im thinking about a function to update all posts relative to the associated user, IE if a user changes their name all associated comments will be updated. Is this possible with the WhereIn() function? Or should i edit the architecture to something more like each document being its own message/comment? Thanks!
An in clause checks if a specific field is equal to one of a set of values, which doesn't apply here.
You might be thinking of array-contains, but that wouldn't work in your current structure either. The array-contains only matches exact an item in the array if it completely/exactly matches the value in the query.
The common way to allow such a query is to add a participants array field to each document where you store the UIDs of all participants in that doc. Then you can do an array-contains query against that.
I have created a review system, in a collection, within a document. In the document I have an array where the average of the ratings is (which when uploading the review are added), but if I upload two equal numbers with FieldValue.arrayUnion, I only get one.
That's the expected behavior of FieldValue.arrayUnion(). According to the API documentation:
Each specified element that doesn't already exist in the array will be added to the end. If the field being modified is not already an array it will be overwritten with an array containing exactly the specified elements.
FieldValue.arrayUnion() will not add an element if it already exists in the array. If you need to do that, you should read the document, modify the array in memory to contain what you want, then update the entire array back to the document.
I need to increment or decrement filed maxQty and the data structure is added in the below images.
Image with the red mark is the filed and I added another image to understand the data structure
Is there any way to do that?
According to the official documentation regarding updating array elements:
If your document contains an array field, you can use arrayUnion() and arrayRemove() to add and remove elements.
Unfortunately, arrayUnion() does not apply to your use-case, as your businessCard array contains objects and not strings. There are two options, one would be to read the entire array, increase the maxQty, and then write the document back on the server. The second one would be to update the document with the help of a Map by manually copying values into it for each of the fields you want to change.
Please also note that the update operation is not compatible with the automatic field mapping that occurs with Java POJO objects. You are allowed only to use Map objects.
I stored an Array as a FieldValue in one of my document in Firestore. Now I want to update one of its element value. As per the documentation I can use arrayRemove or arrayUnion function to remove the element from array but I didn't see any method to update the value of element. Is there any way that I can help me to update the elements' value.
Here I stored array in "patients" field of document. This array represents list of patients. Look at 0th position of element. Here status's value is "current". I want to update this to "processed". Is there anyway that I can do so.
Also is there any way that I can query the elements of array on the basis of the value placed on status key.
As per the documentation I can use arrayRemove or arrayUnion function to remove the element from an array.
There is no way you can use one of those functions to add or remove elements from an array that contains objects. To be able to use those functions, your array should contain for example literal strings. In that way, you can add or remove one of the elements using arrayRemove() or arrayUnion() functions.
I didn't see any method to update the value of an element.
There is no update method. arrayUnion() method will add a new element in the array only if it does not exist. If you want to update an element, you have to remove it first from the array and then add the new one. This is also available in the case of strings and not in the case of objects.
Is there any way that I can help me to update the elements' value.
Yes, two ways in which you can achieve this. The first one would be to get the entire document, get the patients property as a list of hashmaps, iterate through its elements, make the desired changes and write the document back. The second one would be to transform that array into a subcollection where each patient will become a document. In this way, you can simply update add or remove a document using the corresponding functions.
Also is there any way that I can query the elements of the array on the basis of the value placed on the status key.
Using your current document structure, no. If you want to query the patients of a user based on the value of a specific property, you should definitely use the second approach. There is no way you can achieve this using your actual schema.
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