How to add 2 different queries inside an FirestoreRecyclerAdapter?

后端 未结 2 412
终归单人心
终归单人心 2020-12-06 23:22

I have two queries:

Query firstQuery = ref.orderBy(\"name\", Query.Direction.ASCENDING).limit(10);
getData(firstQuery);

Query secondQuery = ref.orderBy(\"pr         


        
相关标签:
2条回答
  • 2020-12-06 23:35

    I ended up using a modified version of adapter class from the Friendly-eats code lab sample.

    The following class allows you add an initial query and then set another one using the FirestoreAdapter.setQuery(query) method.

    import androidx.lifecycle.Lifecycle
    import androidx.lifecycle.LifecycleObserver
    import androidx.lifecycle.LifecycleOwner
    import androidx.lifecycle.OnLifecycleEvent
    import androidx.recyclerview.widget.RecyclerView
    import com.google.firebase.firestore.*
    import com.google.firebase.firestore.EventListener
    import java.util.*
    
    /**
     * RecyclerView adapter for displaying the results of a Firestore [Query].
     *
     * Note that this class forgoes some efficiency to gain simplicity. For example, the result of
     * [DocumentSnapshot.toObject] is not cached so the same object may be deserialized
     * many times as the user scrolls.
     *
     *
     * See the adapter classes in FirebaseUI (https://github.com/firebase/FirebaseUI-Android/tree/master/firestore) for a
     * more efficient implementation of a Firestore RecyclerView Adapter.
     */
    abstract class FirestoreAdapter<VH : RecyclerView.ViewHolder>(private var query: Query,
                                                                  private val lifecycleOwner: LifecycleOwner)
      : RecyclerView.Adapter<VH>(), EventListener<QuerySnapshot>, LifecycleObserver {
    
      private var listener: ListenerRegistration? = null
      private val snapshots = ArrayList<DocumentSnapshot>()
    
      @OnLifecycleEvent(Lifecycle.Event.ON_START)
      fun startListening() {
        if (listener == null) {
          listener = query.addSnapshotListener(this)
        }
      }
    
      @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
      fun stopListening() {
        listener?.apply {
          remove()
          listener = null
        }
    
        snapshots.clear()
        notifyDataSetChanged()
      }
    
      @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
      internal fun cleanup(source: LifecycleOwner) {
        source.lifecycle.removeObserver(this)
      }
    
      override fun onEvent(snapshot: QuerySnapshot?, error: FirebaseFirestoreException?) {
        when {
          error != null -> onError(error)
          else -> {
            // Dispatch the event
            snapshot?.apply {
              for (change in documentChanges) {
                when (change.type) {
                  DocumentChange.Type.ADDED -> onDocumentAdded(change)
                  DocumentChange.Type.MODIFIED -> onDocumentModified(change)
                  DocumentChange.Type.REMOVED -> onDocumentRemoved(change)
                }
              }
              onDataChanged()
            }
          }
        }
      }
    
      protected fun onDocumentAdded(change: DocumentChange) {
        snapshots.add(change.newIndex, change.document)
        notifyItemInserted(change.newIndex)
      }
    
      protected fun onDocumentModified(change: DocumentChange) {
        if (change.oldIndex == change.newIndex) {
          // Item changed but remained in same position
          snapshots[change.oldIndex] = change.document
          notifyItemChanged(change.oldIndex)
        } else {
          // Item changed and changed position
          snapshots.removeAt(change.oldIndex)
          snapshots.add(change.newIndex, change.document)
          notifyItemMoved(change.oldIndex, change.newIndex)
        }
      }
    
      protected fun onDocumentRemoved(change: DocumentChange) {
        snapshots.removeAt(change.oldIndex)
        notifyItemRemoved(change.oldIndex)
      }
    
      fun setQuery(query: Query) {
        stopListening()
    
        // Clear existing data
        snapshots.clear()
        notifyDataSetChanged()
    
        // Listen to new query
        this.query = query
        startListening()
      }
    
      override fun getItemCount(): Int = snapshots.size
    
      protected fun getSnapshot(index: Int): DocumentSnapshot = snapshots[index]
    
      protected open fun onError(exception: FirebaseFirestoreException) {}
    
      protected open fun onDataChanged() {}
    }
    
    0 讨论(0)
  • 2020-12-06 23:44

    There is nothing built-in to combine two queries in a FirestoreRecyclerAdapter.

    The best I can think of is creating a List/array of the combined results in your app code and then using an array adapter. It's not ideal, since you won't be using FirebaseUI.

    Alternatively, have a look at FirebaseUIs FirestorePagingAdapter, which combines multiples pages of (non-realtime) DocumentSnapshots in a single recycler view.

    0 讨论(0)
提交回复
热议问题