LiveData with multiple sources of different types

I don't know am I get your question correctly or not, but if you have a view that work with one list (something like MyItemList) and this list updated or changed by several situations, you must work with MediatorLiveData.

I mean you must have three LiveData that each one responsible for a situation and one MediatorLiveData that notified if each one of them has changed.

see below:

database

fun getListFromServer(id: String): LiveData<List<MyItem>> {
    val dataFromServer = MutableLiveData<List<MyItem>>()

    firestore
      .collection("groups")
      .document(id)
      .collection("items")
          .addSnapshotListener { snapshot, exception ->
              val items = snapshot?.toObjects(MyItem::class.java) ?: emptyList()
              dataFromServer.postValue(items)
      }

    return dataFromServer
}

fun getFilteredData(id: String): LiveData<FilterData> {
    return DAO.user.getFilteredData(id)
}

fun getBookmarkedList(id: String): LiveData<BookmarkData> {
    return DAO.user.getBookmarkedData(id)
}

And in the viewModel you have one MediatorLiveData that observe on these liveDatas till if any data has changed notify view.

viewModel

private val result = MediatorLiveData<<List<MyItem>>()

fun observeOnData(id: String, owner: LifeCycleOwner, observer: Observer<List<MyItem>>) {
   result.observe(owner, observer);

   result.addSource(Database.getListFromServer(id), MyItemList -> {
        if(MyItemList != null)
            result.setValue(MyItemList)
   });
   result.addSource(Database.getFilteredData(id), filterData -> {
        if(filterData != null) {
            val myItemList = result.getValue()
            if (myItemList == null) return

            //here add logic for update myItemList depend On filterData

            result.setValue(myItemList)
        }
   });
   result.addSource(Database.getBookmarkedList(id), bookmarkData -> {
        if(MyItemList != null) {
            val myItemList = result.getValue()
            if (myItemList == null) return

            //here add logic for update myItemList depend On bookmarkData

            result.setValue(myItemList)
        }
   });

}

Your implementation of contents includes several references to outer variables, which makes it hard to follow and keep track of the state. I'd just keep the references as local as possible and trust switchMap(liveData) to do a proper job. The following code should be doing just the same as yours:

val contents = Transformations.switchMap(database.group) { id ->
    val data = MediatorLiveData<Resource<List<MyItem>>()

    if (id == null) {
        data.value = Resource.init(null)
    } else {
        data.value = Resource.loading(null)
        data.addSource(database.getList(id)) {
            data.value = Resource.success(it)
        }
    }

    return liveData
}

In regards of getList(id) you might also want to handle the exception properly.