Leeland Clay
Leeland Clay

Reputation: 132

Query firebase nodes to get counts with dynamic paths

I'm trying to figure out a more elegant way of doing this...

I am storing message objects and want to get the total number of conversations that have new messages. My node structure is like this:

/messages/{userId}/{receipientId}/{messageId}/{message: '', senderId: '', status: 'new|read' }

*** The messageId is an auto generated key from firebase. userId & receipientId are id's from auth.

The first code I wrote to get a number in the badge was this:

firebase.database().ref()
  .child(`/messages/${userId}/${receipientId}`)
  .orderByChild('status')
  .equalTo('new')
  .once('value')
  .then(innerSnapshot => {
    if (innerSnapshot.val() !== null) {
      if (newConversations.findIndex(item => item === entry) === -1) {
        newConversations.push(entry);
      }
    } 
  })
  .catch();

This requires me to wrap it in another query to get all of the receipientId's prior to running a separate query for each item found. It works...but is very brute-forcish.

Essentially, all I need to know is the number of receipientId nodes that has a "status: 'new'" entry somewhere under it.

Upvotes: 0

Views: 110

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598740

You're trying to query across multiple dynamic levels in your JSON, which is not possible with the Realtime Database. See Firebase Query Double Nested and Firebase query if child of child contains a value.

As usual with NoSQL databases, consider modifying/augmenting your data structure to allow the use-case you want. So if you want to know the number of recipients that have a status: 'new', consider storing precisely that: a top-level list of message recipients, with their message statuses. That pretty much the inverse data structure of what you have now, which is why it's somewhat of an inverted index.

Upvotes: 1

Related Questions