Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
597 views
in Technique[技术] by (71.8m points)

firebase - Android - Client-side sorting with FirebaseRecyclerAdapter

I'm building an application with Firebase on Android. The scenario for my application is as follows. Look at the following screen.

Transactions screen

As you can see, in the above screen, I'm displaying a list of transactions based on the user role: Renter and Owner. Also, at the toolbar, user can easily filter any transaction statuses, shown in the following screen.

Transaction status filter

To achieve this scenario, I've modeled my database with the following structure:

- transactionsAll:
    - transactionID1:
        - orderDate: xxx
        - role: Renter / Owner
    - transactionID2:
        ....
- transactionsWaitingApproval:
    - transactionID1:
        - orderDate: xxx
        - role: Renter / Owner

The thing is, in each of the Fragment, I've used an orderByChild query just to display the list of transactions based on the user role in each of the fragment, whether it's the Renter or the Owner, like so

public void refreshRecyclerView(final String transactionStatus) {
    Query transactionsQuery = getQuery(transactionStatus);
    //Clean up old data
    if (mFirebaseRecyclerAdapter != null) {
        mFirebaseRecyclerAdapter.cleanup();
    }

    mFirebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Transaction, TransactionViewHolder>(Transaction.class, R.layout.item_transaction,
            TransactionViewHolder.class, transactionsQuery) {

        @Override
        public int getItemCount() {
            int itemCount = super.getItemCount();

            if (itemCount == 0) {
                mRecyclerView.setVisibility(View.GONE);
                mEmptyView.setVisibility(View.VISIBLE);
            } else {
                mRecyclerView.setVisibility(View.VISIBLE);
                mEmptyView.setVisibility(View.GONE);
            }

            return itemCount;
        }

        @Override
        protected void populateViewHolder(final TransactionViewHolder viewHolder, final Transaction transaction, final int position) {

            final CardView cardView = (CardView) viewHolder.itemView.findViewById(R.id.transactionCardView);
            cardView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            });

            viewHolder.bindToPost(getActivity(), transaction, new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                }
            });
        }
    };

    mRecyclerView.setAdapter(mFirebaseRecyclerAdapter);
    mFirebaseRecyclerAdapter.notifyDataSetChanged();
}

Where the getQuery method is as follows:

private Query getQuery(String transactionStatus) {

    Query transactionsQuery = null;
    int sectionNumber = getArguments().getInt(SECTION_NUMBER);
    if (sectionNumber == 0) { // Renter fragment
        if (transactionStatus == null || transactionStatus.equals(MyConstants.TransactionStatusConstants.allTransactionsValue))
            transactionsQuery = FirebaseDatabaseHelper.getTransactionsAllReference().orderByChild("productRenter").equalTo(UserHelper.getCurrentUser().getUid());
        else if (transactionStatus.equals(MyConstants.TransactionStatusConstants.waitingApprovalValue))
            transactionsQuery = FirebaseDatabaseHelper.getTransactionsWaitingApprovalReference().orderByChild("productRenter").equalTo(UserHelper.getCurrentUser().getUid());
        ...

    }
    if (sectionNumber == 1) { // Owner fragment
        if (transactionStatus == null || transactionStatus.equals(MyConstants.TransactionStatusConstants.allTransactionsValue))
            transactionsQuery = FirebaseDatabaseHelper.getTransactionsAllReference().orderByChild("productOwner").equalTo(UserHelper.getCurrentUser().getUid());
        else if (transactionStatus.equals(MyConstants.TransactionStatusConstants.waitingApprovalValue))
            transactionsQuery = FirebaseDatabaseHelper.getTransactionsWaitingApprovalReference().orderByChild("productOwner").equalTo(UserHelper.getCurrentUser().getUid());
        ...
    }
    return transactionsQuery;
}

With the above query, I've ran out of options to perform another orderByKey/Child/Value on the query. As written in the docs, I can't perform a double orderBy query.

You can only use one order-by method at a time. Calling an order-by method multiple times in the same query throws an error.

The problem: With every new Transaction object pushed to the database, it is shown on the bottom of the recycler view. How can I sort the data based on the orderDate property, in descending order? So that every new transaction will be shown as the first item the recycler view?

In the same documentation page, it is said that:

Use the push() method to append data to a list in multiuser applications. The push() method generates a unique key every time a new child is added to the specified Firebase reference. By using these auto-generated keys for each new element in the list, several clients can add children to the same location at the same time without write conflicts. The unique key generated by push() is based on a timestamp, so list items are automatically ordered chronologically.

I want the items to be ordered chronologically-reversed.

Hopefully someone from the Firebase team can provide me with a suggestion on how to achieve this scenario gracefully.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...