polymerfire: Firebase Query Returns Empty Array even though there are objects in the endpoint

Description

The firebase-query element’s data observer method, which has parameters newData and oldData returns an empty array, preventing transformation of the data in the observer.

Expected outcome

I have an observer _onDataReceived(newData, oldData) function that gets called on change of a firebase-query’s data property. This data is retrieved from a path that only has two items.

I expected the observer function to return an array of two items so that I can transform it in the observer method.

Actual outcome

What actually happens when stepping through observer method is that it gets called two times, but both times newData is an empty array. However, the observer method console.log’s newData both times, and running the observer method without breakpoints shows that the second time the observer method gets called, newData is an array of two objects.

The code is run as if there is no data in newData (both times newData is an empty array)

Steps to reproduce

  1. create a firebase app with an endpoint /test2 that has two objects in it.
  2. create a firebase-test element:
<link rel="import" href="/bower/polymer/polymer.html">
<link rel="import" href="/bower/polymerfire/firebase-auth.html">
<link rel="import" href="/bower/polymerfire/firebase-app.html">
<link rel="import" href="/bower/polymerfire/firebase-query.html">


<dom-module id="test-firebase">
    <template>
        <firebase-app auth-domain="YOUR_AUTH_DOMAIN"
            database-url="YOUR_DATABASE_URL"
            api-key="YOUR_FIREBASE_API_KEY">
        </firebase-app>

        <firebase-auth id="firebaseAuth"
            location="YOUR_DATABASE_LOCATION"
            user="{{user}}">
        </firebase-auth>

        <firebase-query
            path='/test2'
            data="{{data}}">
        </firebase-query>

    </template>

    <script>
        Polymer({
            is: "test-firebase",

            properties: {
                data: {
                    type: Object,
                    observer: '_onDataReceived'
                }
            },

            _onDataReceived: function (newData, oldData) {
                console.log("objects in newData:", newData);
                this.convertedData = [];
                for (item in newData) { 
                    this.push('convertedData', { 'id': item}); 
                }
                console.log('convertedObjects', this.convertedData);
            }
        });
    </script>

</dom-module>

  1. Put a firebase-test element in the page.
  2. Open the page in a web browser.
  3. Inspect Element and look at console.
  4. Add a breakpoint at console.log("objects in newData:", newData);
  5. Refresh page and step through both invocations of the observer method. Notice the value of newData
  6. remove breakpoint.
  7. refresh page. Keep eye on console log.
  8. Notice the value of the second log of newData. The two objects magically appear even though they weren’t initially there in the step through and the observer method.

I tried the data.splices workaround (https://github.com/firebase/polymerfire/issues/67), but that retrieves the same data from firebase following this pattern: retrieves an array of size 1, then an array of size 2 (object 1 and object 2), then an array of size 3 (object 1,2 and 3) etc.

This unnecessarily retrieves the same data multiple time, resulting in a long load time.

–>

Browsers Affected

  • [ X] Chrome

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 5
  • Comments: 21 (1 by maintainers)

Most upvoted comments

Basically the whole example reported in https://beta.webcomponents.org/element/firebase/polymerfire/v0.10.3/firebase-query doesn’t work. Since no change in {{data}} is detected then the list of < sticky-note > is not updated. I think this is a big issue.

@ahilans I think what I can suggest is not to use the firebase-query because it uses the child_added event rather than the value event. If you are not adding a limit value and you want to load everything inside the endpoint, you can just use firebase-document.

<firebase-document
    path="/test2"
    data="{{data}}"
></firebase-document>

then in your script do this:

observers: [
    '_onDataReceived(data.*)'
]

_onDataReceived: function() {
    var newData = this.data;
    var convertedData = [];
    for (var item in newData) { 
        convertedData.push({ 'id': item});    
    }
    this.convertedData = convertedData;
    console.log('convertedObjects', this.convertedData);
}

This would instantaneously (I hope) show the data. The slow down would be of course if you have a thousand points in an endpoint which is caused by the latency of loading a lot of points

If they add it to the docs it will definitely clear up some confusion. Better yet, have all dependencies in the element.