title: How to observe conversations in iOS app powered by Firebase Realtime Database?
body: <p><strong>=====================</strong></p>
  
  <p><strong>I thought about it for a while and proposed a potential solution at the end of the question, do you think it's feasible?</strong></p>
  
  <p><strong>=====================</strong></p>
  
  <p>I'm using Firebase Realtime Database to support chatting in my iOS app. I have a node called "conversations" in database, which is structured like so:</p>
  
  <pre><code>-conversations
      -user_id_1  // This is you
          -recipient_id_1  // id of the user who's chatting with you
              -message_id_1
                  -message: &lt;some_message&gt;
                  -date: &lt;some_date&gt;
              -message_id_2
                  -message: &lt;some_message&gt;
                  -date: &lt;some_date&gt;
          -recipient_id_2
              -message_id_1
                  -message: &lt;some_message&gt;
                  -date: &lt;some_date&gt;
              -message_id_2
                  -message: &lt;some_message&gt;
                  -date: &lt;some_date&gt;
  </code></pre>
  
  <p>Whenever a new message is sent to a user, he should get a notification.</p>
  
  <p>I have thought about using <strong>Push Notification</strong>, i.e. I use Cloud Function Trigger to observe the path:</p>
  
  <pre><code>functions.database.ref('conversations/{uid}/{recipientId}/{messageId}').onCreate((snapshot) =&gt; {
      // Send push notification to user with "uid"
  })
  </code></pre>
  
  <p>However, there's a problem with this, what if the user blocks the push notification of the app? The user is not gonna receive any message while he's not using the app (which is what he wants by turning off push notification), but he's not gonna get any message even when he's in the app. Therefore, I'm thinking, maybe I should use Firebase SDK in my app to observe database like so:</p>
  
  <pre><code>Database
      .database().reference()
      .child("conversations").child(&lt;my_user_id&gt;)
      .observe(.childAdded) { (snapshot) in
      // do stuff with snapshot
  }
  </code></pre>
  
  <p>But then, this only observes newly started conversations, i.e. if the user already had a conversation with, say "person1", and "person1" sends a new message to the user, this observer wouldn't be triggered. Then, I was thinking:</p>
  
  <p>Firstly, Keep the above observer so that I get notified when a new conversation is started</p>
  
  <p>Secondly, Create multiple other observers that listen to my existing conversations:</p>
  
  <pre><code>Database
      .database().reference()
      .child("conversations").child(&lt;my_user_id&gt;).child(&lt;existing_recipient_id&gt;)
      .observe(.childAdded) { (snapshot) in
      // do stuff with snapshot
  }
  </code></pre>
  
  <p>But this way, how do I know all my "existing_recipient_id"? I certainly shouldn't fetch them on start up:</p>
  
  <pre><code>Database
      .database().reference()
      .child("conversations").child(&lt;my_user_id&gt;)
      .observeSingleEvent(of: .value) { (snapshot) in
      // Extract all "existing_recipient_id"
  }
  </code></pre>
  
  <p>Because this fetches all my conversations and their messages, which could potentially be multi-GBs.</p>
  
  <p>I have the following 2 questions:</p>
  
  <ol>
  <li><p>If I have 1,000 conversations with 1,000 people, should I have 1,000 observers in-app? If this wouldn't cause any problem, say performance issue, how do I set up these observers so that I could avoid the problems above?</p></li>
  <li><p>I'm definitely using push notification, in case user is not in the app while a new message is sent to him. But, I don't know whether the user is in app or not, if he is, I already have those observers, push notification seems redundant, and it raises the cost. Is there a way that I can avoid this?</p></li>
  </ol>
  
  <p><strong>Temp solution</strong></p>
  
  <ol>
  <li><p>Write a cloud function that fetches all "existing_recipient_id", which is just an array of strings.</p></li>
  <li><p>In the app, I add a listener that monitors the device's connection state, whenever the device comes back online from offline, also when the app first launches, I call that cloud function to fetch id's of all existing conversations.</p></li>
  <li><p>Add observers to each of those conversations</p></li>
  <li><p>Add observer to listen to new conversation</p></li>
  <li><p>But I still don't know what to do about push notification when user is in-app, I guess I'll do it even though it's redundant</p></li>
  </ol>