1

I'm having this kind of JSON tree:
enter image description here

On Home page of my app, I want to show just list of groups and number of messages in that group.

In normal case I fetch all the chats and show the count of each group chats messages, but doing this will cause a big performance effect if there are more groups.

I found this for web API and outdated, but not for iOS SDK.

So how can I get count of messages from group1 without retrieving all the messages?

Mohammad Zaid Pathan
  • 16,304
  • 7
  • 99
  • 130

1 Answers1

2

How about adding a noOfMessages node under each group, and updating it every time with the group messages count changes. You will have to make a query to count the noOfChildren some time, right? But this way not every time.


For me i just created a func countNodes() which would be fired every time a child is added or you can use a timeInterval in NSTimer, which as you say is expensive.

But with .childAdded you will only receive appended key-value pair not the entire of the node's value, and then all you gotta do is update your noOfMessages node's value with the no of .childAdded count.


As for in your case, change your structure to:-

 chats :{
   group1 : {
         ...
       },
   },
 noOfMessages :{
    group1 : 18,
    group2 : 76,
   ....
   }

Add an observer to your each group of eventType .childAdded.

FIRDatabase.database().reference().child("chats/group1").observeSingleEvent(of: .childAdded, with: {(snap) in

        //Run transaction to update your noOfMessage Count

    }) 

To get the noOfMessages count:-

FIRDatabase.database().reference().child("noOfMessages/group1").observeSingleEvent(of: .value, with: {(snap) in
      let count = snap.value as! Int
 })
Dravidian
  • 9,945
  • 3
  • 34
  • 74
  • Thank for this answer, The only problem I found with this approach is lack of integrity, for example when we add chat message but at the same time Internet disappear or something else happened and count doesn't updated, what should we do in that situation? I was thinking if Firebase gives number of child in given json may be highly helpful with high integrity. – Mohammad Zaid Pathan Oct 15 '16 at 11:17
  • FirebaseDatabasePersistence can be in handy , i suppose. :- https://firebase.google.com/docs/database/ios/offline-capabilities. You can only be so foolProof ;) Also your exact fear is discussed :- https://firebase.google.com/docs/database/ios/read-and-write in write data offline section – Dravidian Oct 15 '16 at 11:20
  • For a way to ensure integrity between mutations of a list and the counter, see [this answer](http://stackoverflow.com/questions/37954217/is-the-way-the-firebase-database-quickstart-handles-counts-secure) (and also [this older answer](http://stackoverflow.com/questions/22971571/how-do-i-prevent-duplicate-voting-while-incrementing-the-vote-count-on-firebase). – Frank van Puffelen Oct 15 '16 at 11:42
  • @FrankvanPuffelen, Should I use fan-out here? Store same data on chat and at the same time update number of item at same time? Is it possible? (fan-out ref: https://firebase.googleblog.com/2015/10/client-side-fan-out-for-data-consistency_73.html) – Mohammad Zaid Pathan Oct 19 '16 at 20:14
  • I would not consider this a case of fanning out the data. But a multi-location update (as the one used in the blog post) is indeed the way to go. – Frank van Puffelen Oct 20 '16 at 04:23
  • @Dravidian , what if there are more than 1k child are there? Is there is any performance issue with that? – Mohammad Zaid Pathan Dec 26 '16 at 18:56
  • Incrementing your value using transactions is innocent enough. I don't think there will be a performance issue.. – Dravidian Dec 26 '16 at 19:19
  • a WHOLE 1k ?! :) – Fattie Nov 16 '17 at 02:42