0

I want to save data to my firebase using firebase-document. It appears that the data is correctly being saved but is immediately being overwritten. Here are the errors I get...

console.log

Sync to memory.
Updating data from Firebase value: Object {comment: "foo", date: "bar", id: "-XXXxxxxxxXXXXXXxxxx", merchant: "baz", status: "bat"…}
app-storage-behavior.html:368

Sync to memory.
app-storage-behavior.html:350
Updating data from Firebase value: Object {date: ""}

See that second paragraph in the log? That's what I don't expect to see. What could be causing this? And what can I do to achieve my desired behavior? Here is my code...

x-el.html
<firebase-document
    id="document"
    app-name="my-firebase"
    data="{{editableItem}}"
    log>
</firebase-document>
...
save: function() {
  return this.$.document.save(this.itemsPath);
}

Edit

Here is a screenshot of console log.

Screenshot of console log

Look at the second Sync to memory log. It describes writing what is essentially an empty object: {date:""} to memory (firebase). This operation overwrites the previous object: {comment: "c", date: "", merchant: "c", status: "new", total: "3"} written to the same location.

Here is the firebase-document.html file in question.

And below are the relevant sections of code.

firebase-document.html
attached: function() {
  this.__refChanged(this.ref, this.ref);
},

detached: function() {
  if (this.ref) {
    this.ref.off('value', this.__onFirebaseValue, this);
  }
},

observers: [
  '__refChanged(ref)'
],

...

__refChanged: function(ref, oldRef) {
  if (oldRef) {
    oldRef.off('value', this.__onFirebaseValue, this);
  }
  if (ref) {
    ref.on('value', this.__onFirebaseValue, this);
  }
},

__onFirebaseValue: function(snapshot) {
  var value = snapshot.val();
  if (value == null) {
    value = this.zeroValue;
  }
  if (!this.new) {
    this.async(function() {
      this.syncToMemory(function() {
        this._log('Updating data from Firebase value:', value); // Causes overwrite
        this.set('data', value);
      });
    });
  }
}
Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207

2 Answers2

1

The side effect of this.$.document.save(this.itemsPath) is that the path of the firebase-document would be reset to point to the new item you've created in your DB. However, this code as the path oneway bound into the firebase-document so every time the data is saved you are repointing the component to a place in your DB with no data. Two way binding and/or no binding path at all, or using an explicit key in save(parentPath, key) so that the target matched editableItemId should clear up you issue.

Westbrook
  • 608
  • 5
  • 9
  • +1 because that gave me something reasonable to try. However, the issue is still present. I deleted the `path` attribute in the `firebase-document` element (I edited the code in the question accordingly to reflect that) and the same errors and behaviors are present. Any ideas what else might be causing this? – Let Me Tink About It Aug 17 '16 at 23:10
  • Beyond this it would be hard to track the error without a live example. I'd want to track what `path` was being set to over the course of the interaction, but I'd also want to see what was going on in the DB. First, I'd check that you're not getting explicit error (particularly permission ones) in the web socket connection to Firebase, and then I'd want to compare the `path` in the component to the data actually found at that path.If you happened to be able to wire up a jsbin or the like, I'd be happy to take a look. – Westbrook Aug 17 '16 at 23:29
1

I've had similar issues before with the 'Sync to memory' thingy. What I did is I make the changes directly using the firebase.database functions like add and set and never attempt to make changes on the data from the < firebase-document >. And I use < firebase-query > instead. As stated in: https://firebase.googleblog.com/2014/05/handling-synchronized-arrays-with-real.html

We have to treat the downloaded data/array as ReadOnly. And make the changes directly in firebase using firebase.database functions. In that way the < firebase-query > listens and updates itself and it's a cycle. For modifying specific changes using IDs though, there's an added arrayfromquery[0].$key data from the < firebase-query > you can use. I guess this is not exactly relevant somehow but I hope it does help :)