1

I have a hypothetical database as bellow

'trees':
    'group1': {
        'tree1' : {
            name: 'A first tree',
            startDate: '10/20/2016'
       },
       'tree2' : {
            name: 'A second tree',
            startDate: '12/20/2016'
        }
     },
     'group2': {
        'tree3' : {
            name: 'A third tree',
            startDate: '12/20/2016'
        },
        'tree4' : {
            name: 'A fourth tree',
            startDate: '5/20/2016'
        },
        'tree5' : {
            name: 'A fifth tree',
            startDate: '10/20/2016'
        }
     }
}

I want to get trees that have startDate equal '5/20/2016' and '12/10/2016' in 'group1' and 'group2'. Ended up with 2 option

  • For each group, I will go through each child key 'startDate', first query orderByChild('startDate') then use equalTo('5/20/2016') then again with '12/10/2016'

    var startDates = ['5/10/2016','12/10/2016']
    var groups = ['group1','group2']
    
    groups.forEach(function(value, index) function() {
    
    firebase.database().ref('trees'+val);
    
    startDates.forEach(function(v,i) {
        userTaskRef.orderByChild('startDate').equalTo(l).once('child_added',                  
            function(result) {
            //some callback code
        })
    })
    

    })

  • Retrieve all trees in 'group1' and 'group2' to sort out in local

    var startDates = ['5/10/2016','12/10/2016']
    var groups = ['group1','group2']
    
    groups.forEach(function(value, index) function() {
        firebase.database().ref('trees'+val);
    
        userTaskRef.once('value', function(rt) {
    
            // for-each for objects with jQuery 
            $.map(rt.val(), function(value, index){
    
                if (dates.indexOf(value.date) >= 0)  {
                   // select this tree
                }
            })
        })
     })
    

Both working well, I realized that the first method would execute more trips from local to server (number of group * number of startDates). While the second method execute same as number of group but will get all data

So I'd appreciate for any advise for this particular case about performance and security (assume that other tree should not be read when not needed)

Cheers

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Hieu Nguyen
  • 474
  • 1
  • 5
  • 21

1 Answers1

4

In general I wouldn't worry too much about the number of roundtrips. The Firebase client pipelines the requests to the server, so they're pretty efficient. See this answer for more information about that.

If we ignore the number of roundtrips, the biggest different between your two approaches is the amount of data you download. In your first approach, the database filters the items and you only download the ones that fall into your date range. In the second approach you download all data and filter client-side.

In the tiny data set above, the difference between these approaches will be negligible. But as you add more and more items, the second approach will start downloading more and more data that your user doesn't need. For that reason I'd recommend against using the second approach.

Note that you can prevent the need for two queries altogether if you change your data structure a bit or add a self-created index to it:

'trees':
    'group1': {
        'tree1' : {
            name: 'A first tree',
            startDate: '10/20/2016'
       },
       'tree2' : {
            name: 'A second tree',
            startDate: '12/20/2016'
        }
     },
     'group2': {
        'tree3' : {
            name: 'A third tree',
            startDate: '12/20/2016'
        },
        'tree4' : {
            name: 'A fourth tree',
            startDate: '5/20/2016'
        },
        'tree5' : {
            name: 'A fifth tree',
            startDate: '10/20/2016'
        }
     }
},
'itemsByDate': {
  '5/20/2016': {
      'group2/tree4': true
  },
  '10/20/2016': {
      'group1/tree1': true,
      'group1/tree5': true
  },
  '12/20/2016': {
      'group1/tree2': true,
      'group2/tree3': true
  },
}

Now you can find the date range with a single query and then load the items with a bunch of direct access once() calls (which are fast due to the pipelining I mentioned earlier).

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807