В моем проекте в Firebase две базы данных. Одна из них - это общая база данных BlogPosts для всех сообщений, а другая - UserPosts для сообщений, отфильтрованных под конкретным пользователем. Из BlogPosts я могу получить необходимые данные, чтобы перейти к конкретному посту в UserPosts (что я сделал в документе, который я добавил сюда). Я хочу сделать систему так, чтобы при удалении с домашней страницы (откуда извлекаются BlogPosts) некоторые сообщения, она удаляла данные как из BlogPosts, так и из UserPosts из базы данных Firebase. Но система вылетает каждый раз, когда я запускаю свое приложение и пытаюсь удалить какой-нибудь пост.
Вот мой конкретный код:
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
//get the profile id from BlogPosts post so that we can reach the same post in Userposts
String profileid = dataSnapshot.child("ProfileId").getValue().toString();
profiledb = FirebaseDatabase.getInstance()
.getReference().child("UserPosts").child(id).child(profileid);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
}) ;
profiledb.removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
databaseReference.removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
ProfileFragment prf = new ProfileFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, prf).commit();
}
});
}
});
Ошибка приведена ниже:
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.tasks.Task com.google.firebase.database.DatabaseReference.removeValue()' on a null object reference
at com.example.zub.projectFirebase.SinglePostFragment$2$4$1.onMenuItemClick(SinglePostFragment.java:327)
Вы должны предоставить другую ссылку на базу данных для всех ваших транзакций.
Пожалуйста, объясните это.
См. Предоставленный мной ответ. Поместите код для удаления profiledb туда, где вы получите ссылку на его базу данных. Таким образом, он получит ссылку перед удалением. Где вы ошибаетесь, так это по-другому запускать код. В случае, если первая транзакция слишком тяжелая для загрузки, она продолжит работу с другими транзакциями и сделает ссылку базы данных нулевой, потому что она не завершится, прежде чем пытаться выполнить другую.
В какой строке кода возникает эта ошибка? Пожалуйста, ответьте @.
@Ineedajob приложение все еще вылетает. Удивительно, но сообщение, которое я хочу удалить, удалено из обеих баз данных. Но приложение все равно вылетает.
@AlexMamo, поскольку обе базы данных удаляют сообщение, которое я удаляю, я предполагаю, что ошибка находится в "databaseReference.removeValue (). AddOnSuccessListener (new OnSuccessListener <Void> ()" в обновленном коде Ineedajob. Приложение вылетает сразу после удаления пост из обеих баз.
«Я думаю», нет, тебе нужно быть уверенным.
@AlexMamo Я только что нашел, в чем проблема. Есть родительский фрагмент SingleFragment, с которого запускается этот конкретный фрагмент. SingleFragment использует данные сообщения. Когда я удаляю сообщение, SingleFragment не может получить данные. Таким образом выдается исключение NullPointerException. Я не понимаю, что я оставил SingleFragment для нового фрагмента и выполняю операцию удаления. Так почему же в SingleFragment есть ошибка? И дайте, пожалуйста, решение.
Где вы ошибаетесь, так это по-другому запускать код. В случае, если первая транзакция слишком тяжелая для загрузки, она продолжит выполнение других транзакций и сделает dbrefnull, потому что он не завершится до попытки другой.
Итак, поместите код для удаления profiledb туда, где вы получите ссылку на его базу данных. Таким образом, он получит ссылку перед удалением.
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
//get the profile id from BlogPosts post so that we can reach the same post in Userposts
String profileid = dataSnapshot.child("ProfileId").getValue().toString();
profiledb = FirebaseDatabase.getInstance()
.getReference().child("UserPosts").child(id).child(profileid);
profiledb.removeValue().addOnSuccessListener(new
OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
databaseReference.removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
ProfileFragment prf = new ProfileFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, prf).commit();
}
});
}
});
@Override
public void onCancelled(@NonNull DatabaseError
databaseError) {
}
}) ;
}
});
Можете ли вы опубликовать свою базу данных и полный исходный код, возможно, ссылку на любой репозиторий
Я даже не знаю, что вы пытаетесь зафиксировать после удаления из базы данных
У меня нет прав на публикацию всего кода, извините :(. См. Мой последний комментарий.
Можете ли вы предоставить здесь ссылку на VCS? предпочтительно github.com
Еще одна вещь, которую мне пришлось сделать помимо кода, - это поместить блок try catch в родительский фрагмент (SinglePostFragment), где он получает тот же пост. Таким образом, после удаления сообщения код игнорирует выборку, и сбоев не происходит.
@Zubayr Хорошая работа!
databaseReference - это ссылка на сообщение в базе данных BlogPosts.