The proper way of adding an index in a nested firebase realtime database structure












0















The structure of by database is as follows:



my-db
|
Users
|
CreatedAt: "SOME_VALUE"
|
Email: "SOME_EMAIL"
|
Mailboxes
|
445566
|
Address: "My address 1"
|
Status: Active
|
112233
|
Address: "My address 2"
|
Status: Active


What I am trying to do is to filter only the users who have an active mailbox with a specific id. I am using firebase cloud functions for that purpose and the way I do it is as follows:



db.ref('/Users')
.orderByChild('mailboxes/' + mailboxId + '/status')
.equalTo('Active')
.once("value", function(snapshot){
snapshot.forEach(function(childSnapshot){
// GET SPECIFIC USER DATA FROM childSnapshot
})
})


It seems to be working fine so far, but I am getting a warning error in firebase functions log saying that:




@firebase/database: FIREBASE WARNING: Using an unspecified index. Your
data will be downloaded and filtered on the client. Consider adding
".indexOn": "mailboxes/445566/status" at /Users to your security rules
for better performance.




I have tried to add an index in the rules file:



{
"rules": {
".read": true,
".write": true,
"users": {
"$userid": {
"mailboxes": {
"$mailboxid": {
".indexOn": ["status"]
}
}
}
}
}
}


but still no success. I am now wondering what is not correct here.










share|improve this question





























    0















    The structure of by database is as follows:



    my-db
    |
    Users
    |
    CreatedAt: "SOME_VALUE"
    |
    Email: "SOME_EMAIL"
    |
    Mailboxes
    |
    445566
    |
    Address: "My address 1"
    |
    Status: Active
    |
    112233
    |
    Address: "My address 2"
    |
    Status: Active


    What I am trying to do is to filter only the users who have an active mailbox with a specific id. I am using firebase cloud functions for that purpose and the way I do it is as follows:



    db.ref('/Users')
    .orderByChild('mailboxes/' + mailboxId + '/status')
    .equalTo('Active')
    .once("value", function(snapshot){
    snapshot.forEach(function(childSnapshot){
    // GET SPECIFIC USER DATA FROM childSnapshot
    })
    })


    It seems to be working fine so far, but I am getting a warning error in firebase functions log saying that:




    @firebase/database: FIREBASE WARNING: Using an unspecified index. Your
    data will be downloaded and filtered on the client. Consider adding
    ".indexOn": "mailboxes/445566/status" at /Users to your security rules
    for better performance.




    I have tried to add an index in the rules file:



    {
    "rules": {
    ".read": true,
    ".write": true,
    "users": {
    "$userid": {
    "mailboxes": {
    "$mailboxid": {
    ".indexOn": ["status"]
    }
    }
    }
    }
    }
    }


    but still no success. I am now wondering what is not correct here.










    share|improve this question



























      0












      0








      0








      The structure of by database is as follows:



      my-db
      |
      Users
      |
      CreatedAt: "SOME_VALUE"
      |
      Email: "SOME_EMAIL"
      |
      Mailboxes
      |
      445566
      |
      Address: "My address 1"
      |
      Status: Active
      |
      112233
      |
      Address: "My address 2"
      |
      Status: Active


      What I am trying to do is to filter only the users who have an active mailbox with a specific id. I am using firebase cloud functions for that purpose and the way I do it is as follows:



      db.ref('/Users')
      .orderByChild('mailboxes/' + mailboxId + '/status')
      .equalTo('Active')
      .once("value", function(snapshot){
      snapshot.forEach(function(childSnapshot){
      // GET SPECIFIC USER DATA FROM childSnapshot
      })
      })


      It seems to be working fine so far, but I am getting a warning error in firebase functions log saying that:




      @firebase/database: FIREBASE WARNING: Using an unspecified index. Your
      data will be downloaded and filtered on the client. Consider adding
      ".indexOn": "mailboxes/445566/status" at /Users to your security rules
      for better performance.




      I have tried to add an index in the rules file:



      {
      "rules": {
      ".read": true,
      ".write": true,
      "users": {
      "$userid": {
      "mailboxes": {
      "$mailboxid": {
      ".indexOn": ["status"]
      }
      }
      }
      }
      }
      }


      but still no success. I am now wondering what is not correct here.










      share|improve this question
















      The structure of by database is as follows:



      my-db
      |
      Users
      |
      CreatedAt: "SOME_VALUE"
      |
      Email: "SOME_EMAIL"
      |
      Mailboxes
      |
      445566
      |
      Address: "My address 1"
      |
      Status: Active
      |
      112233
      |
      Address: "My address 2"
      |
      Status: Active


      What I am trying to do is to filter only the users who have an active mailbox with a specific id. I am using firebase cloud functions for that purpose and the way I do it is as follows:



      db.ref('/Users')
      .orderByChild('mailboxes/' + mailboxId + '/status')
      .equalTo('Active')
      .once("value", function(snapshot){
      snapshot.forEach(function(childSnapshot){
      // GET SPECIFIC USER DATA FROM childSnapshot
      })
      })


      It seems to be working fine so far, but I am getting a warning error in firebase functions log saying that:




      @firebase/database: FIREBASE WARNING: Using an unspecified index. Your
      data will be downloaded and filtered on the client. Consider adding
      ".indexOn": "mailboxes/445566/status" at /Users to your security rules
      for better performance.




      I have tried to add an index in the rules file:



      {
      "rules": {
      ".read": true,
      ".write": true,
      "users": {
      "$userid": {
      "mailboxes": {
      "$mailboxid": {
      ".indexOn": ["status"]
      }
      }
      }
      }
      }
      }


      but still no success. I am now wondering what is not correct here.







      node.js firebase firebase-realtime-database






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 14:44









      Frank van Puffelen

      235k29381407




      235k29381407










      asked Nov 14 '18 at 8:27









      user2128702user2128702

      5261831




      5261831
























          1 Answer
          1






          active

          oldest

          votes


















          1














          An index needs to be defined on the location where you run the query. So since you run your query on /Users, that's where the index needs to be defined. As the error message says:



          {
          "rules": {
          ".read": true,
          ".write": true,
          "users": {
          ".indexOn": "mailboxes/445566/status"
          }
          }
          }


          But you'll immediately notice that this means you'll need an index for each UID, which is not feasible. The reason for this is that the Firebase Database can only query flat lists, it cannot query across multiple levels.



          Your current data structure allows you to efficiently read all mailboxes for a given user. It does not however easily allow you to find all users for a specific mailbox status. To allow the latter, you'll need an additional data structure where you store a list of mailboxes (the entity you're querying), their status (the condition that you're filtering on) and their user (the result you want).



          mailboxes: {
          "445566": {
          "Status": "Active",
          "user": "uid1"
          },
          "112233" {
          "Status": "Active",
          "user": "uid2"
          }
          }


          With the above additional structure, you can use this index:



          "mailboxes": {
          ".indexOn": "Status"
          }


          Next you query this /mailboxes to get all mailboxes with a certain status, and then determine the unique users in there to display.



          Also see:




          • Firebase Query Double Nested

          • Firebase query if child of child contains a value






          share|improve this answer
























          • So, you basically say that having my current data structure (kind of a schema) it is not possible to define an index rule and I need to re-structure it anyway?

            – user2128702
            Nov 14 '18 at 19:34











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53295841%2fthe-proper-way-of-adding-an-index-in-a-nested-firebase-realtime-database-structu%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          An index needs to be defined on the location where you run the query. So since you run your query on /Users, that's where the index needs to be defined. As the error message says:



          {
          "rules": {
          ".read": true,
          ".write": true,
          "users": {
          ".indexOn": "mailboxes/445566/status"
          }
          }
          }


          But you'll immediately notice that this means you'll need an index for each UID, which is not feasible. The reason for this is that the Firebase Database can only query flat lists, it cannot query across multiple levels.



          Your current data structure allows you to efficiently read all mailboxes for a given user. It does not however easily allow you to find all users for a specific mailbox status. To allow the latter, you'll need an additional data structure where you store a list of mailboxes (the entity you're querying), their status (the condition that you're filtering on) and their user (the result you want).



          mailboxes: {
          "445566": {
          "Status": "Active",
          "user": "uid1"
          },
          "112233" {
          "Status": "Active",
          "user": "uid2"
          }
          }


          With the above additional structure, you can use this index:



          "mailboxes": {
          ".indexOn": "Status"
          }


          Next you query this /mailboxes to get all mailboxes with a certain status, and then determine the unique users in there to display.



          Also see:




          • Firebase Query Double Nested

          • Firebase query if child of child contains a value






          share|improve this answer
























          • So, you basically say that having my current data structure (kind of a schema) it is not possible to define an index rule and I need to re-structure it anyway?

            – user2128702
            Nov 14 '18 at 19:34
















          1














          An index needs to be defined on the location where you run the query. So since you run your query on /Users, that's where the index needs to be defined. As the error message says:



          {
          "rules": {
          ".read": true,
          ".write": true,
          "users": {
          ".indexOn": "mailboxes/445566/status"
          }
          }
          }


          But you'll immediately notice that this means you'll need an index for each UID, which is not feasible. The reason for this is that the Firebase Database can only query flat lists, it cannot query across multiple levels.



          Your current data structure allows you to efficiently read all mailboxes for a given user. It does not however easily allow you to find all users for a specific mailbox status. To allow the latter, you'll need an additional data structure where you store a list of mailboxes (the entity you're querying), their status (the condition that you're filtering on) and their user (the result you want).



          mailboxes: {
          "445566": {
          "Status": "Active",
          "user": "uid1"
          },
          "112233" {
          "Status": "Active",
          "user": "uid2"
          }
          }


          With the above additional structure, you can use this index:



          "mailboxes": {
          ".indexOn": "Status"
          }


          Next you query this /mailboxes to get all mailboxes with a certain status, and then determine the unique users in there to display.



          Also see:




          • Firebase Query Double Nested

          • Firebase query if child of child contains a value






          share|improve this answer
























          • So, you basically say that having my current data structure (kind of a schema) it is not possible to define an index rule and I need to re-structure it anyway?

            – user2128702
            Nov 14 '18 at 19:34














          1












          1








          1







          An index needs to be defined on the location where you run the query. So since you run your query on /Users, that's where the index needs to be defined. As the error message says:



          {
          "rules": {
          ".read": true,
          ".write": true,
          "users": {
          ".indexOn": "mailboxes/445566/status"
          }
          }
          }


          But you'll immediately notice that this means you'll need an index for each UID, which is not feasible. The reason for this is that the Firebase Database can only query flat lists, it cannot query across multiple levels.



          Your current data structure allows you to efficiently read all mailboxes for a given user. It does not however easily allow you to find all users for a specific mailbox status. To allow the latter, you'll need an additional data structure where you store a list of mailboxes (the entity you're querying), their status (the condition that you're filtering on) and their user (the result you want).



          mailboxes: {
          "445566": {
          "Status": "Active",
          "user": "uid1"
          },
          "112233" {
          "Status": "Active",
          "user": "uid2"
          }
          }


          With the above additional structure, you can use this index:



          "mailboxes": {
          ".indexOn": "Status"
          }


          Next you query this /mailboxes to get all mailboxes with a certain status, and then determine the unique users in there to display.



          Also see:




          • Firebase Query Double Nested

          • Firebase query if child of child contains a value






          share|improve this answer













          An index needs to be defined on the location where you run the query. So since you run your query on /Users, that's where the index needs to be defined. As the error message says:



          {
          "rules": {
          ".read": true,
          ".write": true,
          "users": {
          ".indexOn": "mailboxes/445566/status"
          }
          }
          }


          But you'll immediately notice that this means you'll need an index for each UID, which is not feasible. The reason for this is that the Firebase Database can only query flat lists, it cannot query across multiple levels.



          Your current data structure allows you to efficiently read all mailboxes for a given user. It does not however easily allow you to find all users for a specific mailbox status. To allow the latter, you'll need an additional data structure where you store a list of mailboxes (the entity you're querying), their status (the condition that you're filtering on) and their user (the result you want).



          mailboxes: {
          "445566": {
          "Status": "Active",
          "user": "uid1"
          },
          "112233" {
          "Status": "Active",
          "user": "uid2"
          }
          }


          With the above additional structure, you can use this index:



          "mailboxes": {
          ".indexOn": "Status"
          }


          Next you query this /mailboxes to get all mailboxes with a certain status, and then determine the unique users in there to display.



          Also see:




          • Firebase Query Double Nested

          • Firebase query if child of child contains a value







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 14 '18 at 14:43









          Frank van PuffelenFrank van Puffelen

          235k29381407




          235k29381407













          • So, you basically say that having my current data structure (kind of a schema) it is not possible to define an index rule and I need to re-structure it anyway?

            – user2128702
            Nov 14 '18 at 19:34



















          • So, you basically say that having my current data structure (kind of a schema) it is not possible to define an index rule and I need to re-structure it anyway?

            – user2128702
            Nov 14 '18 at 19:34

















          So, you basically say that having my current data structure (kind of a schema) it is not possible to define an index rule and I need to re-structure it anyway?

          – user2128702
          Nov 14 '18 at 19:34





          So, you basically say that having my current data structure (kind of a schema) it is not possible to define an index rule and I need to re-structure it anyway?

          – user2128702
          Nov 14 '18 at 19:34




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53295841%2fthe-proper-way-of-adding-an-index-in-a-nested-firebase-realtime-database-structu%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Florida Star v. B. J. F.

          Danny Elfman

          Retrieve a Users Dashboard in Tumblr with R and TumblR. Oauth Issues