Search code examples
firebasepolymerfirebase-realtime-databasepolymer-1.0firebase-polymer

Polymer + Firebase: firebase-document, data being overwritten?


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

Solution

  • 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.