FirebaseRecyclerAdapter 问题,删除数据时空对象引用
Issue with FirebaseRecyclerAdapter, on a null object reference when delete data
Firebase 数据库的显示工作正常,但是当我尝试从数据库中删除项目时,应用程序崩溃,尽管删除发生了。写入字符串中的空对象引用:
String postDescription = dataSnapshot.child("desc").getValue().toString();
这是我的代码:
public class PostFragment extends Fragment {
private RecyclerView recyclerPost;
private DatabaseReference postReference;
private View view;
private LinearLayoutManager layoutManager;
public PostFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_post, container, false);
recyclerPost = view.findViewById(R.id.recycler_post);
postReference = FirebaseDatabase.getInstance().getReference().child("Posts");
postReference.keepSynced(true);
layoutManager = new LinearLayoutManager(getContext());
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
recyclerPost.setHasFixedSize(true);
recyclerPost.setLayoutManager(layoutManager);
return view;
}
@Override
public void onStart() {
super.onStart();
Query query = postReference.orderByChild("timestamp");
FirebaseRecyclerOptions<Posts> options =
new FirebaseRecyclerOptions.Builder<Posts>()
.setQuery(query, Posts.class)
.build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Posts, PostViewHolder>(options) {
@Override
protected void onBindViewHolder(@NonNull final PostViewHolder holder, int position, @NonNull final Posts model) {
final String postId = getRef(position).getKey();
postReference.child(postId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String postDescription = dataSnapshot.child("desc").getValue().toString();
holder.postDesc.setText(postDescription);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
holder.delBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
postReference.child(postId).removeValue();
}
});
}
@NonNull
@Override
public PostViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.blog_item, viewGroup, false);
return new PostViewHolder(view);
}
};
adapter.startListening();
recyclerPost.setAdapter(adapter);
}
public class PostViewHolder extends RecyclerView.ViewHolder {
private TextView postDesc;
private Button delBtn;
private View view;
public PostViewHolder(@NonNull View itemView) {
super(itemView);
view = itemView;
postDesc = (TextView) view.findViewById(R.id.post_description);
delBtn = (Button) view.findViewById(R.id.del_post_btn);
}
}
}
请告诉我这个问题的解决方法。
您可以尝试以下方法:
postReference.child(postId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
String postDescription = dataSnapshot.child("desc").getValue().toString();
holder.postDesc.setText(postDescription);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
您可以使用方法 exists()
:
public boolean exists ()
Returns true if the snapshot contains a non-null value.
它将检查数据快照是否在
数据库,如果它不在数据库中那么你可以添加一个小吃店或吐司。
更多信息在这里:
每次将 post 添加到 adapter/list 视图时,您现在都会在 onBindViewHolder
中创建一个带有 addValueEventListener
的侦听器。此侦听器从数据库中获取值,然后继续侦听更改,直到您将其删除。由于您永远不会删除这些侦听器,因此随着时间的推移它们会累加起来,事情可能会变得不同步。
最简单的解决方案是使用 addListenerForSingleValueEvent
:
@Override
protected void onBindViewHolder(@NonNull final PostViewHolder holder, int position, @NonNull final Posts model) {
final String postId = getRef(position).getKey();
postReference.child(postId).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String postDescription = dataSnapshot.child("desc").getValue().toString();
holder.postDesc.setText(postDescription);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
当您使用 addListenerForSingleValueEvent
时,侦听器会在 onDataChange
第一次触发后立即被删除。
Firebase 数据库的显示工作正常,但是当我尝试从数据库中删除项目时,应用程序崩溃,尽管删除发生了。写入字符串中的空对象引用:
String postDescription = dataSnapshot.child("desc").getValue().toString();
这是我的代码:
public class PostFragment extends Fragment {
private RecyclerView recyclerPost;
private DatabaseReference postReference;
private View view;
private LinearLayoutManager layoutManager;
public PostFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_post, container, false);
recyclerPost = view.findViewById(R.id.recycler_post);
postReference = FirebaseDatabase.getInstance().getReference().child("Posts");
postReference.keepSynced(true);
layoutManager = new LinearLayoutManager(getContext());
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
recyclerPost.setHasFixedSize(true);
recyclerPost.setLayoutManager(layoutManager);
return view;
}
@Override
public void onStart() {
super.onStart();
Query query = postReference.orderByChild("timestamp");
FirebaseRecyclerOptions<Posts> options =
new FirebaseRecyclerOptions.Builder<Posts>()
.setQuery(query, Posts.class)
.build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Posts, PostViewHolder>(options) {
@Override
protected void onBindViewHolder(@NonNull final PostViewHolder holder, int position, @NonNull final Posts model) {
final String postId = getRef(position).getKey();
postReference.child(postId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String postDescription = dataSnapshot.child("desc").getValue().toString();
holder.postDesc.setText(postDescription);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
holder.delBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
postReference.child(postId).removeValue();
}
});
}
@NonNull
@Override
public PostViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.blog_item, viewGroup, false);
return new PostViewHolder(view);
}
};
adapter.startListening();
recyclerPost.setAdapter(adapter);
}
public class PostViewHolder extends RecyclerView.ViewHolder {
private TextView postDesc;
private Button delBtn;
private View view;
public PostViewHolder(@NonNull View itemView) {
super(itemView);
view = itemView;
postDesc = (TextView) view.findViewById(R.id.post_description);
delBtn = (Button) view.findViewById(R.id.del_post_btn);
}
}
}
请告诉我这个问题的解决方法。
您可以尝试以下方法:
postReference.child(postId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
String postDescription = dataSnapshot.child("desc").getValue().toString();
holder.postDesc.setText(postDescription);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
您可以使用方法 exists()
:
public boolean exists ()
Returns true if the snapshot contains a non-null value.
它将检查数据快照是否在 数据库,如果它不在数据库中那么你可以添加一个小吃店或吐司。
更多信息在这里:
每次将 post 添加到 adapter/list 视图时,您现在都会在 onBindViewHolder
中创建一个带有 addValueEventListener
的侦听器。此侦听器从数据库中获取值,然后继续侦听更改,直到您将其删除。由于您永远不会删除这些侦听器,因此随着时间的推移它们会累加起来,事情可能会变得不同步。
最简单的解决方案是使用 addListenerForSingleValueEvent
:
@Override
protected void onBindViewHolder(@NonNull final PostViewHolder holder, int position, @NonNull final Posts model) {
final String postId = getRef(position).getKey();
postReference.child(postId).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String postDescription = dataSnapshot.child("desc").getValue().toString();
holder.postDesc.setText(postDescription);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
当您使用 addListenerForSingleValueEvent
时,侦听器会在 onDataChange
第一次触发后立即被删除。