title: LiveData with multiple sources of different types
body: <p>I currently have a project that contains a list of <code>MyItem</code>, and using Firebase/LiveData. It's structured into groups, and each group has items.</p>
  
  <p>I want to be able to update this list if any of the following happen:</p>
  
  <ol>
  <li>An item is updated (on the backend through Firebase)</li>
  <li>A filter is changed (a separate table on Firebase for each user)</li>
  <li>An item is bookmarked (a separate table on Firebase for each user)</li>
  </ol>
  
  <p>To get the list of contents, I have a function like this to return LiveData that will update whenever an item is updated (#1).</p>
  
  <h2>database</h2>
  
  <pre><code>getList(id: String): LiveData&lt;List&lt;MyItem&gt;&gt; {
      val data = MutableLiveData&lt;List&lt;MyItem&gt;&gt;()
  
      firestore
          .collection("groups")
          .document(id)
          .collection("items")
              .addSnapshotListener { snapshot, exception -&gt;
                  val items = snapshot?.toObjects(MyItem::class.java) ?: emptyList()
  
                  // filter items 
  
                  data.postValue(items)
          }
  
      return data
  }
  </code></pre>
  
  <p>And within my ViewModel, I have logic for handling that case. </p>
  
  <h2>viewmodel</h2>
  
  <pre><code>private val result = MediatorLiveData&lt;Resource&lt;List&lt;MyItem&gt;&gt;&gt;()
  
  private var source: LiveData&lt;List&lt;MyItem&gt;&gt;? = null
  val contents: LiveData&lt;Resource&lt;List&lt;MyItem&gt;&gt;&gt;
      get() {
          val group = database.group
  
          // if the selected group is changed.
          return Transformations.switchMap(group) { id -&gt;
              // showing loading indicator
              result.value = Resource.loading(null)
  
              if (id != null) {
                  // only 1 source for the current group
                  source?.let {
                      result.removeSource(it)
                  }
  
                  source = database.getList(id).also {
                      result.addSource(it) {
                          result.value = Resource.success(it)
                      }
                  }
  
                  // how to add in source of filter changes?
  
              } else {
                  result.value = Resource.init(null)
              }
              return@switchMap result
          }
      }
  </code></pre>
  
  <p>The logic is pretty complex, and hard to follow. Is there a better way to structure this to handle multiple different changes? What's the best way to store the user's current filters?</p>
  
  <p>Thanks.</p>