I am trying to create a real-time RecyclerView every time a user adds an item to a certain Database reference in Firebase. Here is my model class:
@IgnoreExtraProperties
public class Poll {
private String question;
private String image_URL;
public Poll() {
}
public Poll(String Question, String Image_URL){
this.question = Question;
this.image_URL = Image_URL;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
question = question;
}
public String getImage_URL() {
return image_URL;
}
public void setImage_URL(String image_URL) {
image_URL = image_URL;
}
@Exclude
public Map<String, Object> toMap(){
HashMap<String, Object> result = new HashMap<>();
result.put("question", question);
result.put("image_URL", image_URL);
return result;
}
Here is the class where I save data to Firebase. It is actually being written to Firebase, so I can confirm that I am writing it correctly:
mSubmitPollCreation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//TODO: Need to check if poll requirements are added, i.e. Question, Answer, ......
//check if image has been loaded first
if (resultImageURL == null){
Toast.makeText(getApplicationContext(),getResources().getString(R.string.no_image_selected),Toast.LENGTH_LONG).show();
return;
}
Poll poll = new Poll(mCreatePollQuestion.getText().toString(), resultImageURL);
Map <String, Object> pollMap = poll.toMap();
String key = mBaseRef.child("Polls").push().getKey();
Map<String, Object> childUpdates = new HashMap<String, Object>();
childUpdates.put("/Polls/" + key, pollMap);
mBaseRef.updateChildren(childUpdates);
Intent toHomeActivity = new Intent(CreateActivity.this, HomeActivity.class);
toHomeActivity.putExtra("viewpager_position", 2);
startActivity(toHomeActivity);
}
});
I want the recyclerview to live update on all devices as an item is added. Here is the fragment I use to populate the RecyclerView using the Firebase UI library. As I add data/write to Firebase as listed in the previous code snippet, I am not seeing any live updates on any devices:
public class LiveFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private RecyclerView mRecyclerview;
private DatabaseReference mBaseRef;
private DatabaseReference mPollsRef;
private LinearLayoutManager mLayoutManager;
private FirebaseRecyclerAdapter <Poll, PollHolder> mFireAdapter;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public LiveFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment LiveFragment.
*/
// TODO: Rename and change types and number of parameters
public static LiveFragment newInstance(String param1, String param2) {
LiveFragment fragment = new LiveFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View v = inflater.inflate(R.layout.fragment_new, container, false);
mRecyclerview = (RecyclerView) v.findViewById(R.id.new_RecyclerView);
mBaseRef = FirebaseDatabase.getInstance().getReference();
mPollsRef = mBaseRef.child("Polls");
if (mRecyclerview != null){
mRecyclerview.setHasFixedSize(true);
}
mLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL
);
mRecyclerview.setLayoutManager(mLayoutManager);
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onStart() {
super.onStart();
mFireAdapter = new FirebaseRecyclerAdapter<Poll, PollHolder>(
Poll.class,
R.layout.latest_item,
PollHolder.class,
mPollsRef
){
@Override
protected void populateViewHolder(PollHolder viewHolder, Poll model, int position) {
viewHolder.mPollQuestion.setText(model.getQuestion());
Picasso.with(getActivity().getApplicationContext())
.load(model.getImage_URL())
.fit()
.into(viewHolder.mPollImage);
Log.v("QUESTION", model.getQuestion());
Log.v("IMAGE", model.getImage_URL());
}
};
mRecyclerview.setAdapter(mFireAdapter);
}
@Override
public void onStop() {
super.onStop();
if (mFireAdapter != null){
mFireAdapter.cleanup();
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public static class PollHolder extends RecyclerView.ViewHolder {
TextView mPollQuestion;
ImageView mPollImage;
public PollHolder(View itemView) {
super(itemView);
mPollQuestion = (TextView) itemView.findViewById(R.id.latest_item_question);
mPollImage = (ImageView) itemView.findViewById(R.id.pollThumbNailImage);
}
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
EDIT: I believe the data being written to Firebase is null for some reason, as the Logs for the Question
and ImageURL
are not returning any data.
Your
Poll
setter methods are missingthis
:And replace this code:
with:
Also move the code that creates
mFireAdapter
and sets it onmRecyclerview
fromonStart()
to end ofonCreateView()
:The documentation provides an example.