0

My database structure looks like this (simplified):

{
  "articles": {
    "-uniqueId1": {
      "title": "Article 1",
      "category": "news"
    },
    "-uniqueId2": {
      "title": "Article 2",
      "category": "other"
    },
    "-uniqueId3": {
      "title": "Article 3",
      "category": "news"
    },
    "-uniqueId4": {
      "title": "Article 4",
      "category": "news"
    }
  },
  "articlesByCategory": {
    "news": {
      "-uniqueId1": true,
      "-uniqueId3": true,
      "-uniqueId4": true
    },
    "other": {
      "-uniqueId2": true
    }
  }
}

The query needs to fetch articles where a specific article's category isn't within. Does that make sense? Say, if uniqueId2 is of category "other", the query would only fetch articles within "news" and all other existing categories. But since the list may contain, say millions of articles, I have to be as specific as possible and not fetch articles that doesn't match this exact criteria. Therefor, a query like below would be ideal:

const ref = firebase.database().ref("articlesByCategory");
ref.orderByChild("-uniqueId2").equalTo(null).once("value", function(snapshot) {
  console.log(snapshot.key);
});

Here I am searching for categories where a specific property is absent (where a property equals to null). This is explained here: Firebase: Query to exclude data based on a condition

However, doing a query like this requires me to index every article's unique id on "/articlesByCategory" in the security rules. But it would be unrealistic and non-optimal to dynamically add new article ids inside the ".indexOn" array as that would end up with millions of unique (auto-generated) ids:

{
  "articles": {
    ".read": true,
    ".write": true
  },
  "articlesByCategory": {
    ".read": true,
    ".write": true,
    ".indexOn": ["-uniqueId1", "-uniqueId2", "-uniqueId3", "-uniqueId4"...] // List would be endless!
  }
}

So how is this achievable? Why am I seeing these sorts of structures (inverted indexing) as ideal solutions everywhere on StackOverflow, but no one seems to tackle this issue?

Community
  • 1
  • 1
Nordling Art
  • 857
  • 2
  • 9
  • 19

1 Answers1

0

Firebase only can query order statements on nodes with auto-generated ids, and when you've defined your own keys, firebase is unable to perform any sorting/ordering

The ideal way to generate keys is

firebase.getInstance().getReference("articles").push(myArticle);

this will result in a slightly different database structure like

{
"12dakj137_9": { // this is a auto-generated id
"article1": {
  "title": "Article 1",
  "category": "news"
},
"12asjh_123": {
  "title": "Article 2",
  "category": "other"
},...
}

Now firebase is able to order/sort and the way you do this is by

firebase.getInstance().child("articles").orderByChild("category").equalTo("other");
xxfast
  • 697
  • 5
  • 14
  • "article1", "article" etc are unique ids. I have changed them in the first post to "-uniqueId1" etc for better understanding. Anyhow, the way you do the query will fetch articles within category "other". That's not what I'm trying to do. I want to fetch articles that _doesn't_ belong to "other", in which I have to query by an inverted index inside "articlesByCategory", looking for categories that doesn't contain the article by id "-uniqueId2" (because that one has category "other"). – Nordling Art Mar 20 '17 at 08:57