Android Firebase Database Adding items with keys to recycler view

狂风中的少年 提交于 2020-01-05 05:09:13

问题


I was trying to add & show messages dynamically in recycler view but I could not figure out how to send proper data type to it's adapter. In "getNewMessage(dataSnapshot) " function, I have to add all messages to list and send it to recycler view via adapter. I tried both
MessageModel model = dataSnapshot.getValue(MessageModel.class)
and creating a SampleModel that contains List<MessageModel> list, and
SampleModel model = dataSnapshot.getValue(SampleModel.class);
They didn't work. Here sample JSON file that created with sending message:

"chat" : {
"-Ksbjn0yCEB6EXhNNCM5" : {
  "author" : "Ali Alacan",
  "content" : "dummy content",
  "date" : "Mon Aug 28 10:29:50 GMT+03:00 2017",
  "id" : "H6huNPUggjtugjsERPCRSAp1"
},
"-KsbjpUtjp0oeipjjxMI" : {
  "author" : "Ali Alacan",
  "content" : "dummy content",
  "date" : "Mon Aug 28 10:30:00 GMT+03:00 2017",
  "id" : "H6huNPUggjtugjsERPCRSAp1"
}

I'm adding new messages with code below which I learnt from firebase docs.

 @Exclude
public Map<String, Object> toMap(MessageModel messageModel) {
    HashMap<String, Object> result = new HashMap<>();
    result.put("id", messageModel.getId());
    result.put("author", messageModel.getAuthor());
    result.put("content", messageModel.getContent());
    result.put("date", messageModel.getDate());
    return result;
}

private void sendMessage() {
    if (!TextUtils.isEmpty(etMessage.getText())) {
        Date currentTime = Calendar.getInstance().getTime();
        String key = firebaseDatabase.push().getKey();
        MessageModel message = new MessageModel(UserData.getInstance().getUserId(), UserData.getInstance().getName(), "dummy content", currentTime.toString());
        Map<String, Object> messageValues = toMap(message);
        Map<String, Object> childUpdates = new HashMap<>();
        childUpdates.put("/chat/" + key, messageValues);
        childUpdates.put("/user-chat/" + UserData.getInstance().getUserId() + "/" + key, messageValues);
        firebaseDatabase.updateChildren(childUpdates);

    } else {
        Snackbar snackbar = Snackbar
                .make(getActivity().findViewById(R.id.dashboard_container), "Enter a message please ! " + UserData.getInstance().getName(), Snackbar.LENGTH_LONG);
        snackbar.show();
    }
}

My MessageModel is:

public class MessageModel {
String id;
String author;
String content;
String date;

public String getDate() {
    return date;
}

public void setDate(String date) {
    this.date = date;
}

public MessageModel(String id, String author, String content, String date) {
    this.id = id;
    this.author = author;
    this.content = content;
    this.date = date;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getAuthor() {
    return author;
}

public void setAuthor(String author) {
    this.author = author;
}

public String getContent() {
    return content;
}

public void setContent(String content) {
    this.content = content;
}

public MessageModel() {

}

}

And firebase listener

 firebaseDatabase.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            getNewMessage(dataSnapshot);
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            //   getNewMessage(dataSnapshot);
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            // taskDeletion(dataSnapshot);
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

RecyclerView Adapter:

public class MyMessageRecyclerViewAdapter extends RecyclerView.Adapter<MyMessageRecyclerViewAdapter.ViewHolder> {

private final List<MessageModel> mValues;
private final OnListFragmentInteractionListener mListener;

public MyMessageRecyclerViewAdapter(List<MessageModel> items, OnListFragmentInteractionListener listener) {
    mValues = items;
    mListener = listener;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_chat, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    holder.mItem = mValues.get(position);
    holder.mIdView.setText(mValues.get(position).getId());
    holder.mContentView.setText(mValues.get(position).getContent());
    holder.mAuthor.setText(mValues.get(position).getAuthor());
    holder.mDate.setText(mValues.get(position).getDate());
    holder.mView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (null != mListener) {
                // Notify the active callbacks interface (the activity, if the
                // fragment is attached to one) that an item has been selected.
                mListener.onListFragmentInteraction(holder.mItem);
            }
        }
    });
}

@Override
public int getItemCount() {
    return mValues.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
    public final View mView;
    public final TextView mIdView;
    public final TextView mContentView;
    TextView mAuthor;
    TextView mDate;
    public MessageModel mItem;

    public ViewHolder(View view) {
        super(view);
        mView = view;
        mIdView = (TextView) view.findViewById(R.id.id);
        mContentView = (TextView) view.findViewById(R.id.content);
        mAuthor = (TextView) view.findViewById(R.id.author);
        mDate = (TextView) view.findViewById(R.id.date);

    }

    @Override
    public String toString() {
        return super.toString() + " '" + mContentView.getText() + "'";
    }
}

Sorry for reading such a long post and thank you for your time.


回答1:


You don't need to use your toMap anymore, it is making you more confused on what you're doing since You already have a POJO.

Make a List in your Activity.

ArrayList<MessageModel> myListModel = new ArrayList<MessageModel>();

Do this on your firebase Listener. Make a List on your Activity

This is for Child Added.

 @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {

            MessageModel tempMessage = dataSnapshot.getValue(MessageModel.class);

            myListModel.add(tempRace);

        }

Now That you have a List Model. By using the onChildAdeed by Firebase. Use this to your supply your Adapter Model and apply it.

IMPORTANT FOR FIREBASE. In everyquery for the fire base, if you need to do something AFTER the anything else is done ex: "onChildAdded" You would need to add another listener to THE SAME DatabaseReference in your case. I have no idea, you did not include your activity even your DatabaseReference so I would provide one.

DatabaseReference myReference = firebaseDatabase.getReferane("chat");
myReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            MyMessageRecyclerAdapter myMessageAdapter= new MyMessageRecyclerAdapter(myListModel, listener);

//now you have to apply this to the RecyclerView.
   yourWhateverNameofTheRecyclerview.SetAdapter(myMessageAdater);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });


来源:https://stackoverflow.com/questions/45914759/android-firebase-database-adding-items-with-keys-to-recycler-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!