I have a database with the following structure:
I need to update the order's amount child value and then add a new child updatedAt which will have the timestamp of this update.
I use an object of which contains the paths that I want to update and then call ref.update(dataToBeUpdated).
The problem is that the children that I didn't update as the timestamp is removed when I call update() .. it acts like I rewrite the order node and not editing some of its children.. any help?
UPDATE :
Here is how the code looks like :
var dataToUpdate = { [orderPath] : { 'amount': newAmount, 'updatedAt': firebase.database.ServerValue.TIMESTAMP } } return ref.update(dataToUpdate)
It's over writing your data, most likely because you aren't providing the full-path. For example if you are only providing ref.child("postID").update(update) you're overwriting everything under that "postID". I can't really provide an exact solution without seeing your data and code. If you update your post I can provide additional details, but for now try this: ref.child("amount").update(newAmount) and ref.child("updatedAt").update(newTimestamp)
The first one should overwrite the old amount and the second one should add the child updatedAt with your timestamp.
Another way would be to download all the existing data for that order update it locally and then re-upload the whole thing.
Take a look at the update documentation
Related
I need to update a field in a nested object with a dynamic key.
the path could look like this: level1.level2.DYNAMIC_KEY : updatedValue
The update-method deletes everything else on level1 instead of only updating the field in the nested object. The update() acts more like a set(). What am I doing wrong?
I tried the following already:
I read the documentation https://firebase.google.com/docs/firestore/manage-data/add-data#update-data
but that way it is a) static and b) still deletes the other fields.
Update fields in nested objects
If your document contains nested objects, you can use "dot notation" to reference nested fields within the document when you call update()
This would be static and result in
update({
'level1.level2.STATIC_KEY' : 'updatedValue'
});
Then I found this answer https://stackoverflow.com/a/47296152/5552695
which helped me to make the updatepath dynamic.
The desired solution after this could look like
field[`level1.level2.${DYNAMIC_KEY}`] = updateValue;
update(field);
But still: it'll delete the other fields in this path.
UPDATE:
The Structure of my Doc is as follows:
So inside this structure i want to update only complexArray > 0 > innerObject > age
Writing the above path into the update() method will delete everything else on the complexArray-level.
A simple update on first-level-fields works fine and lets the other first-level-fields untouched.
Is it possible, that firestore functions like update() can only act on the lowest field-level on an document. And as soon as i put complex objects into an document its not possible to select such inner fields?
I know there would be the solution to extract those "complex" objects into separate collections + documents and put these into my current lowest document level. I think this would be a more accurate way to stick to the FireStore principles. But on Application side it is easier to work with complex object than to always dig deeper in firestore collection + document structure.
So my current solution is to send the whole complex object into the update() method even though I just changed only one field on application side.
Have you tried using the { merge: true } option in your request?
db
.collection("myCollection")
.doc("myDoc")
.set(
{
level1: { level2: { myField: "myValue" } }
},
{ merge: true }
)
I had created the firebase database with some values and to avoid the duplication, I had maintained the other child in the database. This child only gets created if the record gets added if more 1 or more than one record is available. Now my question is how I can create the child even if there is no value in it as I want to write firebase rule for the validation of the data.
Please help.
I'm assuming you're using javascript. If so, you can push an object with empty strings as their values. For example:
function pushEmptyChildren() {
var ref = firebase.database().ref('yourDatabase');
var yourDatabase = {
childOne: "",
childTwo:"",
childThree:""
}
ref.push(yourDatabase);
}
Hope this answers your question.
I'm currently have the exact same issue as outlined in this article:
https://medium.com/#danbroadbent/firebase-multi-path-updates-updating-denormalized-data-in-multiple-locations-b433565fd8a5
Currently the Firebase single node .update() function will not overwrite other same level child nodes.
However when using multi-location ref.update() all other child nodes in the same level are overwriten, essentially acting as a .set() function.
Is there someway I can actually run multi-location .update() without overwriting all same level child nodes?
Based on this github issue: https://github.com/EddyVerbruggen/nativescript-plugin-firebase/issues/313
One possible workaround would be defining each field you want to update as separate update, and update it as a part of atomic update, that way you would actually update each individual field needed to be updated?
var companiesPath = 'companies/company_name';
var usersPath = 'users/user_nickname';
var data = {};
data[companiesPath] = 'Best Company Name';
data[usersPath] = 'John';
firebase.update(data);
So you can't update the complete object, you need to target the individual fields of that object. I just tested it and this works...
I am new to Web UI, Dojo, Java etc. If you are referring any advance topic please give some reading reference. It will help.
Context:
I have Gridx design using JsonStore, which takes a target + id for URL. With fixed "id" Grid loads well.
I have Dynamic Tree. It is working fine with lazy-loading etc.
Objective:
Based on click (or dblclick) event for a given node in Tree, I have to load Gridx with data. Hence, if tree node "id":7 is clicked, then JsonStore: /target/7 should be fetched and get loaded in Gridx.
Issues:
As you can guess, at start there is no valid "id" property to fill in JsonStore. In click event handler of tree, I will get this value, upon a user click. Hence, can't call gridx.startup() in "ready". Though I have "placed" the widget in "ready".
Hence, I have following snippet to handle,
<
// this function is called from tree event handler
function LatestTabGridxLoad( id ) {
console.log( "ID %s fetched.", id );
LatestTabGridxStore.idProperty = id;
LatestTabGridx.startup();
LatestTabGridx.body.refresh();
}
ready(function()
{
TabLatestAssetTree.startup();
LatestTabGridx.placeAt( "ReportMiddleTabLatestCenterContainer" );
}
Now, trouble is, at first time loading, JsonStore GET fired with /target/ alone, without any "id" without any user click. Hence, server responds with 405. Subsequently, when user clicks, again same HTTP GET without "id" results in HTTP 405. I am not able to somehow feed "id" to the GET URL. I have checked JSON, it is in perfect shape, as it works in standalone table, that is declarative(ly) defined.
Please suggest me ways to link a TREE node through its "id" to Gridx. Also suggest, if approach I am taking is right way to solve this problem.
Sorry, misunderstanding of the question. I thought it was about gridx tree but it is about regular gridx controlled by another widget.
The problem is in this line:
console.log( "ID %s fetched.", id );
LatestTabGridxStore.idProperty = id;
'idProperty' is the name of the JSON attribute which stores the ID. This will not change with each selection. If it is not set, JsonStore will assume it to be 'id'. What you intended to do was to modify the target property of the store to include the ID. This can done directly and will look something like the following (details are application specific)
LatestTabGridxStore.target = (someURL) + '/' + id;
After that, the content of gridx needs to be replaced using the new store setting. There are few ways to do it, the simplest being destroying the current gridx instance and replacing it with another one which uses the altered store.
I want to write a background program that will monitor the _changes feed of a CouchDB, and possibly update the document. The problem is that the update causes another _change, and I get an endless loop! What's the best way to avoid this?
For example, here is the specific scenario: I have a CouchApp where users modify documents through their browser. I also have a python program that creates a PDF version of a document and then attaches it as an attached file to the document itself. My problem is that doing the PUT Attachment to upload the PDF also triggers a document change. I have to be able to tell whether a change is being caused by the PDF upload, or not. It seems like it should be easy, but I can't think of a simple way to do it. I would rather keep the PDF generator program be "stateless", keeping any required state in the db itself.
Now, this can easily be done if I require that users who change the document set some sort of flag on the document to indicate that it needs to be processed. The trick is how to do it without requiring that.
I have come to the conclusion that a "_changes" listener should never modify the document that it listens to. In my case I decided to attach my PDF file to a separate document, in a separate "database" within couchdb, but using the same "_id" to make it easy to correlate. That way I don't trigger a "_change" on the same documents that I am listening to. I could not get past the need to require every client that changes the document to somehow "flag" it as requiring processing ( by deleting the existing attachment, or otherwise setting some "dirty" flag ). After much pondering, I think that this will be a rule-of-thumb for me : that you must not modify a document upon receiving a "_change" notification for that document. Has anyone else reached the same conclusion?
Use a filter function and and filter out the second change – either by the document structure change or by setting an additional flag to the changed document:
function(doc, req)
{
if(!doc.hasStructuralChange) { //fix this
return true;
}
return false;
}
or
function(doc, req)
{
if(!doc.changed) { //set doc.changed during first update
return true;
}
return false;
}
Edit: You can check for an attachment via if (doc._attachments)