Issue with FirebaseRecyclerAdapter, on a null object reference when delete data
up vote
0
down vote
favorite
The display from the Firebase database works fine, but when I try to delete an item from the database, the application crashes, although the deletion occurs. Writes on a null object reference in the string:
String postDescription = dataSnapshot.child("desc").getValue().toString();
Here is my code:
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);
}
}
}
Please tell me the solution to this problem.
android firebase firebase-realtime-database recycler-adapter firebaseui
add a comment |
up vote
0
down vote
favorite
The display from the Firebase database works fine, but when I try to delete an item from the database, the application crashes, although the deletion occurs. Writes on a null object reference in the string:
String postDescription = dataSnapshot.child("desc").getValue().toString();
Here is my code:
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);
}
}
}
Please tell me the solution to this problem.
android firebase firebase-realtime-database recycler-adapter firebaseui
If the application crashes, your logcat should contain an error message and stack trace. Please look those up, and ad them to your question.
– Frank van Puffelen
Nov 11 at 15:29
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
The display from the Firebase database works fine, but when I try to delete an item from the database, the application crashes, although the deletion occurs. Writes on a null object reference in the string:
String postDescription = dataSnapshot.child("desc").getValue().toString();
Here is my code:
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);
}
}
}
Please tell me the solution to this problem.
android firebase firebase-realtime-database recycler-adapter firebaseui
The display from the Firebase database works fine, but when I try to delete an item from the database, the application crashes, although the deletion occurs. Writes on a null object reference in the string:
String postDescription = dataSnapshot.child("desc").getValue().toString();
Here is my code:
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);
}
}
}
Please tell me the solution to this problem.
android firebase firebase-realtime-database recycler-adapter firebaseui
android firebase firebase-realtime-database recycler-adapter firebaseui
edited Nov 11 at 15:28
Frank van Puffelen
222k25363389
222k25363389
asked Nov 11 at 14:08
Binary
51
51
If the application crashes, your logcat should contain an error message and stack trace. Please look those up, and ad them to your question.
– Frank van Puffelen
Nov 11 at 15:29
add a comment |
If the application crashes, your logcat should contain an error message and stack trace. Please look those up, and ad them to your question.
– Frank van Puffelen
Nov 11 at 15:29
If the application crashes, your logcat should contain an error message and stack trace. Please look those up, and ad them to your question.
– Frank van Puffelen
Nov 11 at 15:29
If the application crashes, your logcat should contain an error message and stack trace. Please look those up, and ad them to your question.
– Frank van Puffelen
Nov 11 at 15:29
add a comment |
2 Answers
2
active
oldest
votes
up vote
0
down vote
accepted
You can try the following:
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) {
}
});
You can use the method exists()
:
public boolean exists ()
Returns true if the snapshot contains a non-null value.
It will check if the datasnapshot is in the
database, if it is not in the database then you can add a snackbar or a toast.
More information here:
https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot#exists()
add a comment |
up vote
1
down vote
Every time a post is added to the adapter/list view, you now create a listener with addValueEventListener
in your onBindViewHolder
. This listener gets the value from the database, and then keeps listening for changes until you remove it. Since you never remove these listeners, over time they add up and things likely get out of sync.
The simplest solution is to use 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
}
});
When you use addListenerForSingleValueEvent
, the listener is removed right after onDataChange
fires for the first time.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
You can try the following:
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) {
}
});
You can use the method exists()
:
public boolean exists ()
Returns true if the snapshot contains a non-null value.
It will check if the datasnapshot is in the
database, if it is not in the database then you can add a snackbar or a toast.
More information here:
https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot#exists()
add a comment |
up vote
0
down vote
accepted
You can try the following:
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) {
}
});
You can use the method exists()
:
public boolean exists ()
Returns true if the snapshot contains a non-null value.
It will check if the datasnapshot is in the
database, if it is not in the database then you can add a snackbar or a toast.
More information here:
https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot#exists()
add a comment |
up vote
0
down vote
accepted
up vote
0
down vote
accepted
You can try the following:
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) {
}
});
You can use the method exists()
:
public boolean exists ()
Returns true if the snapshot contains a non-null value.
It will check if the datasnapshot is in the
database, if it is not in the database then you can add a snackbar or a toast.
More information here:
https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot#exists()
You can try the following:
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) {
}
});
You can use the method exists()
:
public boolean exists ()
Returns true if the snapshot contains a non-null value.
It will check if the datasnapshot is in the
database, if it is not in the database then you can add a snackbar or a toast.
More information here:
https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot#exists()
answered Nov 11 at 14:30
Peter Haddad
19.8k83955
19.8k83955
add a comment |
add a comment |
up vote
1
down vote
Every time a post is added to the adapter/list view, you now create a listener with addValueEventListener
in your onBindViewHolder
. This listener gets the value from the database, and then keeps listening for changes until you remove it. Since you never remove these listeners, over time they add up and things likely get out of sync.
The simplest solution is to use 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
}
});
When you use addListenerForSingleValueEvent
, the listener is removed right after onDataChange
fires for the first time.
add a comment |
up vote
1
down vote
Every time a post is added to the adapter/list view, you now create a listener with addValueEventListener
in your onBindViewHolder
. This listener gets the value from the database, and then keeps listening for changes until you remove it. Since you never remove these listeners, over time they add up and things likely get out of sync.
The simplest solution is to use 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
}
});
When you use addListenerForSingleValueEvent
, the listener is removed right after onDataChange
fires for the first time.
add a comment |
up vote
1
down vote
up vote
1
down vote
Every time a post is added to the adapter/list view, you now create a listener with addValueEventListener
in your onBindViewHolder
. This listener gets the value from the database, and then keeps listening for changes until you remove it. Since you never remove these listeners, over time they add up and things likely get out of sync.
The simplest solution is to use 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
}
});
When you use addListenerForSingleValueEvent
, the listener is removed right after onDataChange
fires for the first time.
Every time a post is added to the adapter/list view, you now create a listener with addValueEventListener
in your onBindViewHolder
. This listener gets the value from the database, and then keeps listening for changes until you remove it. Since you never remove these listeners, over time they add up and things likely get out of sync.
The simplest solution is to use 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
}
});
When you use addListenerForSingleValueEvent
, the listener is removed right after onDataChange
fires for the first time.
answered Nov 11 at 15:33
Frank van Puffelen
222k25363389
222k25363389
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53249546%2fissue-with-firebaserecycleradapter-on-a-null-object-reference-when-delete-data%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
If the application crashes, your logcat should contain an error message and stack trace. Please look those up, and ad them to your question.
– Frank van Puffelen
Nov 11 at 15:29