angular - Firebase query if child of child contains a value -


the structure of table is:

  • chats
  • --> randomid
  • -->--> participants
  • -->-->--> 0: 'name1'
  • -->-->--> 1: 'name2'
  • -->--> chatitems

etc

what trying query chats table find chats hold participant passed in username string.

here have far:

 subscribechats(username: string) {     return this.af.database.list('chats', {         query: {             orderbychild: 'participants',             equalto: username, // how check if participants contain username         }     });  } 

a few problems here:

  • you're storing set array
  • you can index on fixed paths

set vs array

a chat can have multiple participants, modelled array. not ideal data structure. each participant can in chat once. using array, have:

participants: ["puf", "puf"] 

that not have in mind, data structure allows it. can try secure in code , security rules, easier if start data structure implicitly matches model better.

my rule of thumb: if find writing array.contains(), should using set.

a set structure each child can present @ once, naturally protects against duplicates. in firebase you'd model set as:

participants: {   "puf": true } 

the true here dummy value: important thing we've moved name key. if i'd try join chat again, noop:

participants: {   "puf": true } 

and when you'd join:

participants: {   "john": true,   "puf": true } 

this direct representation of requirement: collection can contain each participant once.

you can index fixed paths

with above structure, could query chats in with:

ref.child("chats").orderbychild("participants/john").equalto(true) 

the problem require define index on `participants/john":

{   "rules": {     "chats": {       "$chatid": {         "participants": {           ".indexon": ["john", "puf"]         }       }     }   } } 

this work , perform great. each time new joins chat app, you'll need add index. that's not scaleable model. we'll need change our data structure allow query want.

invert index - pull categories up, flattening tree

second rule of thumb: model data reflect show in app.

since looking show list of chat rooms user, store chat rooms each user:

userchatrooms: {   john: {     chatroom1: true,     chatroom2: true   },   puf: {     chatroom1: true,     chatroom3: true   } } 

now can determine list of chat rooms with:

ref.child("userchatrooms").child("john") 

and loop on keys each room.

you'll have 2 relevant lists in app:

  • the list of chat rooms specific user
  • the list of participants in specific chat room

in case you'll have both lists in database.

chatroomusers   chatroom1     user1: true     user2: true   chatroom2     user1: true     user3: true userchatrooms   user1:     chatroom1: true     chatroom2: true   user2:     chatroom1: true   user2:     chatroom2: true 

i've pulled both lists top-level of tree, since firebase recommends against nesting data.

having both lists normal in nosql solutions. in example above we'd refer userchatrooms inverted index of chatroomsusers.


Comments

Popular posts from this blog

account - Script error login visual studio DefaultLogin_PCore.js -

xcode - CocoaPod Storyboard error: -