firebasefirebase-realtime-databasepolymerpolymer-2.xpolymerfire

How to initialize 'settings' at an empty Firebase node in Polymer 2.x using firebase-document?


I want to implement <firebase-document> to fetch and apply user settings. I am using this page as a guide.

When I load the page with no data at the /users/{{userId}}/settings node in my firebase, I expect to see the object { new: 'initial', j: 5, o: 'N' }) loaded there. However, I actually see no change to the node in my firebase.

What am I doing wrong and how can I achieve my desired bahavior?

settings.html
<firebase-document
  path="/users/{{userId}}/settings"
  data="{{data}}">
</firebase-document>

<script>
Polymer({
  properties: {
    uid: String,
    data: {
      type: Object,
      observer: 'dataChanged'
    }
  },

  dataChanged: function (newData, oldData) {
    // if settings have not been set yet, initialize with initial value
    if(!newData && !oldData){
      this.set('data', { new: 'initial', j: 5, o: 'N' });
    }
  }
});
</script>

Edit: Answering the questions by @HakanC's comment:

Does {{userId}} have a value when executed?

Yes.

Is there data at the path /users/{{userId}}/settings?

No. There is no /settings node when the user first logs in. But I do have code that successfully creates a node at /users/{{userId}}. And that node is present when this element executes its script.

Console log whether you arrive this.set line.

I do arrive there—multiple times. The first time, the logged value of data is undefined. The second time, the logged value of data is {}.


Solution

  • As you mentioned above that there is no data at the path, then you need to change if conditions. Something like:

    if(newData === undefined){
    

    instead of;

    if(!newData && !oldData){
    

    EDIT:

    static get properties() { return { 
                uid: String,
                data:{
                   type:Object,
                   value() {return{}; }
                  }
                }
              }
          static get observers() { return [ 'dataChanged(data)' ]} 
    
    
                constructor() {
                  super();
                }
    
                ready() {
                    super.ready();
                    setTimeout(()=> {
                      this.set('data', undefined); //Retrieving data async from firebase.           
                    },500)
                }
    
        dataChanged(data) {
        // if data has not been set then, initialize with new value
          console.log(data);
          if(!data){
            this.set('data', { new: 'initial', j: 5, o: 'N' });
          }
        }     
    

    DEMO