Firebase RecyclerView无法加载新数据 [英] Firebase RecyclerView Not Loading New Data

查看:146
本文介绍了Firebase RecyclerView无法加载新数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当用户将某个项目添加到Firebase中的某个数据库引用时,我正试图创建一个实时RecyclerView。这是我的模型类:

$ $ p $ code $ @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $私人字符串题;
私人字符串image_URL;
$ b $ 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(问题,问题);
result.put(image_URL,image_URL);
返回结果;



$ b

这里是我将数据保存到Firebase的类。它实际上是写给Firebase的,所以我可以确认我写的是正确的:

  mSubmitPollCreation.setOnClickListener(new View。 OnClickListener(){
@Override
public void onClick(View v){
$ b // TODO:需要检查是否添加投票需求,即问题,答案,.. ....
//检查图像是否已经被加载
if(resultImageURL == null){
Toast.makeText(getApplicationContext(),getResources()。getString(R.string (),toast.LENGTH_LONG).show();
return;
}

轮询轮询=新轮询(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);
}
});

我想让recyclerview在所有设备上实时更新。以下是我用来使用Firebase UI库填充RecyclerView的片段。在前面的代码片段中列出的Firebase中添加数据/写入时,我没有在任何设备上看到任何实时更新:

  public class LiveFragment extends Fragment {
// TODO:重命名参数参数,选择匹配
的名字//片段初始化参数,例如ARG_ITEM_NUMBER
private static final String ARG_PARAM1 =param1;
private static final String ARG_PARAM2 =param2;

private RecyclerView mRecyclerview;
私人DatabaseReference mBaseRef;
private DatabaseReference mPollsRef;
私有LinearLayoutManager mLayoutManager;

private FirebaseRecyclerAdapter< Poll,PollHolder> mFireAdapter;


// TODO:重命名和更改参数类型
private String mParam1;
private String mParam2;

private OnFragmentInteractionListener mListener;

public LiveFragment(){
//所需的空公共构造函数

$ b $ **
*使用此工厂方法创建
*这个片段的新实例使用提供的参数。
*
* @param param1参数1.
* @param param2参数2.
* @return片段LiveFragment的新实例。
* /
// TODO:重命名和更改参数的类型和数量
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);



$覆盖
public View onCreateView(LayoutInflater inflater,ViewGroup容器,
Bundle savedInstanceState){
//膨胀这个片段的布局
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;

$ b $ // TODO:将方法,更新参数和钩子方法重命名为UI事件
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
$ {b
$ b @Override
protected void populateViewHolder(PollHolder viewHolder,Poll model,int position){
viewHolder.mPollQuestion.setText(model.getQuestion());
Picasso.with(getActivity()。getApplicationContext())
.load(model.getImage_URL())
.fit()$ b $ .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(查看itemView){
super(itemView);

mPollQuestion =(TextView)itemView.findViewById(R.id.latest_item_question);
mPollImage =(ImageView)itemView.findViewById(R.id.pollThumbNailImage);



$ **
这个接口必须由包含这个
*段的活动来实现,以允许一个交互在这个片段中被传送
*给该活动以及该
*活动中可能包含的其他片段。
*< p>
*参阅Android培训课程< a href =
*http://developer.android.com/training/basics/fragments/communicating.html
*>与其他片段< / a>了解更多信息。
* /
public interface OnFragmentInteractionListener {
// TODO:更新参数类型和名称
void onFragmentInteraction(Uri uri);


$ / code $ / $ p

编辑:我相信写入Firebase的数据是由于某些原因,因为问题 ImageURL 的日志不会返回任何数据。

$ Poll setter方法缺少 this
解决方案

$ p $ public void setQuestion(String question){
this.question = question;


public void setImage_URL(String image_URL){
this.image_URL = image_URL;

$ / code>

并替换此代码:

 映射< String,Object> pollMap = poll.toMap(); 
String key = mBaseRef.child(Polls)。push()。getKey();
地图< String,Object> childUpdates = new HashMap< String,Object>();
childUpdates.put(/ Polls /+ key,pollMap);
mBaseRef.updateChildren(childUpdates);



 < code $ mBaseRef.child(Polls)。push()。setValue(poll,new DatabaseReference.CompletionListener(){
@Override $ b $ public void onComplete(DatabaseError databaseError,DatabaseReference databaseReference){
if(databaseError == null){
Log.i(Poll,onComplete:SUCCESS);
} else {
Log.w(Poll, onComplete:,databaseError.toException());
}
}
});

同时移动创建 mFireAdapter 的代码,将它设置在 mRecyclerview onStart()的结尾onCreateView()

  // ... 
mRecyclerview.setLayoutManager(mLayoutManager);
mFireAdapter = ...;
mRecyclerview.setAdapter(mFireAdapter);

return v;

文档

b

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 missing this:

public void setQuestion(String question) {
    this.question = question;
}

public void setImage_URL(String image_URL) {
    this.image_URL = image_URL;
}

And replace this code:

    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);

with:

mBaseRef.child("Polls").push().setValue(poll, new DatabaseReference.CompletionListener() {
    @Override
    public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
        if (databaseError == null) {
            Log.i("Poll", "onComplete: SUCCESS");
        } else {
            Log.w("Poll", "onComplete: ", databaseError.toException());
        }
    }
});

Also move the code that creates mFireAdapter and sets it on mRecyclerview from onStart() to end of onCreateView():

//...
mRecyclerview.setLayoutManager(mLayoutManager);
mFireAdapter = ...;
mRecyclerview.setAdapter(mFireAdapter);

return v;

The documentation provides an example.

这篇关于Firebase RecyclerView无法加载新数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆