0

Here's my Firebase Data Structure:

{
  "companies": {
    "-Ke_b8p6OBaz1VCeovAH": {
      "display_name": "First User's Company",
      "users": {
        "ir7jjLPA3fXCVsdc4OzzSiH9RJd2": "admin"
      }
    },
    "-Ke_cmhDaIeGJjFwsDI1": {
      "display_name": "First User's Second Company",
      "users": {
        "ir7jjLPA3fXCVsdc4OzzSiH9RJd2": "admin"
      }
    },
    "-Ke_b9OgwY2IBdj5szmJ": {
      "display_name": "Second User's Company",
      "users": {
        "5XcpmN7DgEWNnmWZucyQiOh4TJt2": "admin"
      }
    }
  },

  "users": {
    "ir7jjLPA3fXCVsdc4OzzSiH9RJd2": {
      "display_name": "First User"
    },
    "5XcpmN7DgEWNnmWZucyQiOh4TJt2": {
      "display_name": "Second User"
    }
  }
}

I'm trying to do a query on this data (via. REST for example):

example.firebase.com/companies.json?orderBy="users/ir7jjLPA3fXCVsdc4OzzSiH9RJd2"

My hope is to return

{
  "-Ke_b8p6OBaz1VCeovAH": {
    "display_name": "First User's Company",
    "users": {
      "ir7jjLPA3fXCVsdc4OzzSiH9RJd2": "admin"
    }
  },
  "-Ke_cmhDaIeGJjFwsDI1": {
    "display_name": "First User's Second Company",
    "users": {
      "ir7jjLPA3fXCVsdc4OzzSiH9RJd2": "admin"
    }
  }
}

Instead, I get

{
  "error": "Index not defined, add \".indexOn\": \"users/ir7jjLPA3fXCVsdc4OzzSiH9RJd2\", for path \"/companies\", to the rules"
}

Here's my Firebase Security Rules

{
  "rules": {
    ".read": true,
    ".write": true,

    // Companies
    "companies": {
      ".indexOn": ["display_name", "users"],
    }
  }
}

It's not feasible to update security rules indexing for every user, so how would I handle this?

1 Answer 1

1

Firebase does not support "filtering" in the class sense you are accustomed to. With your current data structure, you would either need to:

  1. Query all companies and filter on your target user client-side, or
  2. Restructure your users collection to add an attribute indicating which companies the user was an admin of. You could then obtain the user record in one query, and then in a second, query the records for the companies that user is an admin of.

These options sound horrible, but believe it or not, this was specifically the case Firebase was designed to "be fast" at handling. It makes up for code/query inefficiencies through massive scale, so you need to forget a lot of SQL-specific best practices when working with it, like normalizing data, efficient query/join operations, etc. Despite what seems like extra work, if you actually benchmark the operations (and particularly if you enable options such as persistance/caching) you can equal or exceed SQL-environment performance even with these extra steps. Think of it like RISC vs CISC where RISC is Firebase and CISC is SQL.

Sign up to request clarification or add additional context in comments.

4 Comments

"Firebase does not support filtering/searching of any kind." This statement seems misleading in this context. Not searching per se, but orderBy + equalTo is a simple filter and applicable to @Cody's problem. I'm not well versed in the REST API but sorting on a child of a child, called deep querying, is certainly possible in the SDKs.
I'd indeed rephrase that first sentence, since there's an entire section in the Firebase documentation about ordering and filtering data: firebase.google.com/docs/database/web/….
@TravisChristian - I've read that article, as well as the one Frank posted. However, I haven't been able to query the way I'm referring to above. With deep querying they reference, the keys are always the same, i.e. height, weight, etc. I'm looking for querying on keys that will change. Keys that are user uid. Also, storing these ids as the key in a dictionary is the recommended storage practice in the firebase database. firebase.google.com/docs/database/web/structure-data#fanout
Sorry guys, I don't see how orderBy + equalTo in any way addresses Cody's original question. Firebase's own docs explicitly describe data structure changes for those coming from SQL-land to address these kinds of questions, and I think it's time for us to all admit that "how do I filter...?" is the #1 question for new Firebase devs. I don't think the running assumption that there are "alternatives" is hitting the mark with new devs. orderBy+equalTo solves a specific problem... but not the one everybody asks about.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.