Top questions from Stack Overflow and Twitter with Frank van Puffelen, Part II - #AskFirebase

By: Firebase

129   2   3887

Uploaded on 02/22/2017

Add the #AskFirebase playlist: https://goo.gl/W3Jm9b
Subscribe to the new Firebase Channel: https://goo.gl/9giPHG

Questions from this episode:

0:18 - How many concurrent read and write requests can Firebase support? Read Puf's answer on Stack Overflow: https://goo.gl/U8rbuB

1:49 - Is it normal that the snapshots are retrieved in the same order as they're requested? Read Puf's answer on Stack Overflow: https://goo.gl/Dd1N8J and even more info here: https://goo.gl/ortK11

5:09 - Is it possible to use wildcard on Firebase Rules like “.write”: "auth != null && auth.email === ‘*@company.com’”?

6:17 - Can Firebase security rules check unique values of a child? Read Puf's answer on Stack Overflow: https://goo.gl/sQFzLT

More info!

8:34 - Learn more about Firebase in a Weekend: Android, with Udacity: https://goo.gl/DMuUb1

8:34 - Learn more about Firebase in a Weekend: iOS, with Udacity: https://goo.gl/1TrEJL

8:45 - Watch "The Firebase Database for SQL Developers" video series: https://goo.gl/o7Bjs5

Add the Firecasts playlist! https://goo.gl/n2XqG1

Music by http://terramonk.com

Comments (6):

By anonymous    2017-09-20

Update: we now also cover this question in an AskFirebase episode.

Loading many items from Firebase doesn't have to be slow, since you can pipeline the requests. But your code is making this impossible, which indeed will lead to suboptimal performance.

In your code, you request an item from the server, wait for that item to return and then load the next one. In a simplified sequence diagram that looks like:

Your app                     Firebase 
                             Database

        -- request item 1 -->
                               S  L
                               e  o
                               r  a
                               v  d
                               e  i
        <-  return item  1 --  r  n
                                  g
        -- request item 2 -->
                               S  L
                               e  o
                               r  a
                               v  d
                               e  i
                               r  n
        <-  return item  2 --     g
        -- request item 3 -->
                 .
                 .
                 .
        -- request item 30-->
                               S  L
                               e  o
                               r  a
                               v  d
                               e  i
                               r  n
                                  g
        <-  return item 30 --

In this scenario you're waiting for 30 times your roundtrip time + 30 times the time it takes to load the data from disk. If (for the sake of simplicity) we say that roundtrips take 1 second and loading an item from disk also takes one second that least to 30 * (1 + 1) = 60 seconds.

In Firebase applications you'll get much better performance if you send all the requests (or at least a reasonable number of them) in one go:

Your app                     Firebase 
                             Database

        -- request item 1 -->
        -- request item 2 -->  S  L
        -- request item 3 -->  e  o
                 .             r  a
                 .             v  d
                 .             e  i
        -- request item 30-->  r  n
                                  g
        <-  return item  1 --     
        <-  return item  2 --      
        <-  return item  3 --
                 .
                 .
                 .
        <-  return item 30 --

If we again assume a 1 second roundtrip and 1 second of loading, you're waiting for 30*1 + 1 = 31 seconds.

So: all requests go through the same connection. Given that, the only difference between get(1), get(2), get(3) and getAll([1,2,3]) is some overhead for the frames.

I set up a jsbin to demonstrate the behavior. The data model is very simple, but it shows off the difference.

function loadVideosSequential(videoIds) {
  if (videoIds.length > 0) {
    db.child('videos').child(videoIds[0]).once('value', snapshot => {
      if (videoIds.length > 1) {
        loadVideosSequential(videoIds.splice(1), callback)
      }
    });
  }
}

function loadVideosParallel(videoIds) {
  Promise.all(
    videoIds.map(id => db.child('videos').child(id).once('value'))
  );
}

For comparison: sequentially loading 64 items takes 3.8 seconds on my system, while loading them pipelined (as the Firebase client does natively) it takes 600ms. The exact numbers will depend on your connection (latency and bandwidth), but the pipelined version should always be significantly faster.

Original Thread

By anonymous    2017-09-20

When you call orderBy... or other methods, it returns a new query. So you're now creating a new query for each uid that you then don't use. To keep it, you'd need newUidsQuery = newUidsQuery.equalTo(uid).

But that won't solve the problem yet, because a query can only order/filter on a single property and value. See Query based on multiple where clauses in firebase.

Better news is that this doesn't matter much here, since you can just retrieve the items one at a time. Unlike what you might expect, that's not significantly slower than retrieving them in one go. See Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly or watch this episode of #AskFirebase: https://youtu.be/66lDSYtyils?t=1m49s

Original Thread

By anonymous    2017-09-20

In the JSON you shared there is no path /users/email. So this rule will never be true:

root.child('users/email').val() === auth.token.email

You cannot in security rules search under a path for a specific value. You can check for the existence of a specific key though. See Firebase security rules to check unique value of a child #AskFirebase, Firebase android : make username unique or my answer in this #AskFirebase video: https://youtu.be/66lDSYtyils?t=6m15s.

Original Thread

Recommended Books

    Submit Your Video

    If you have some great dev videos to share, please fill out this form.