#java #android #firebase #firebase-realtime-database
#java #Android #firebase #firebase-realtime-database
Вопрос:
Я извлекаю данные из своей базы данных на основе userId
, затем я вставляю данные в a listview
и показываю их через диалоговое окно.
Поведение, которого я ждал, заключается в том, что я получу все созданные пользователем обмены и вставлю их в список, чтобы он мог выбрать один из них. Но код работает нормально, только если у него есть только один swap в базе данных, как это обычно выглядит. Но если у него есть два обмена, то обмен внутри списка будет умножен на два.
И если их три, то данные будут повторяться три раза и так далее. Я не знаю, что происходит в моем коде здесь, и надеюсь, что есть кто-то, кто может помочь мне в этой проблеме. как я могу избавиться от дублирующихся элементов в списке?
private void fetchChooseList() {
DatabaseReference shiftSwapDb = FirebaseDatabase.getInstance().getReference().child("swaps").child("shift_swaps");
final List<SwapDetails> swapBodyList = new ArrayList<>();
Collections.reverse(swapBodyList);
shiftProfileAdapter = new ShiftProfileAdapter(ProfileActivityShift.this, R.layout.shift_profile_list_item, swapBodyList);
listView = chooseShiftProfileDialog.findViewById(R.id.listShiftProfileChooseDialog);
listView.setAdapter(shiftProfileAdapter);
shiftSwapDb.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.exists()) {
SwapDetails swapDetails = dataSnapshot.getValue(SwapDetails.class);
if (swapDetails.getSwapperID().equals(fromID)) {
shiftProfileAdapter.add(swapDetails);
}
}
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) { }
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) { }
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) { }
@Override
public void onCancelled(DatabaseError databaseError) { }
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
progressBar_ShiftProfileChooseDialog.setVisibility(View.VISIBLE);
listView.setVisibility(View.INVISIBLE);
SwapDetails swapDetails = swapBodyList.get(adapterView.getCount() - i - 1);
fromLoginID = swapDetails.getSwapperLoginID();
fromImageUrl = swapDetails.getSwapperImageUrl();
fromName = swapDetails.getSwapperName();
fromPhone = swapDetails.getSwapperPhone();
fromEmail = swapDetails.getSwapperEmail();
fromCompanyBranch = swapDetails.getSwapperCompanyBranch();
fromAccount = swapDetails.getSwapperAccount();
fromShiftDate = swapDetails.getSwapShiftDate();
fromShiftDay = swapDetails.getSwapperShiftDay();
fromShiftTime = swapDetails.getSwapperShiftTime();
fromPreferredShift = swapDetails.getSwapperPreferredShift();
String child = fromID fromShiftDay fromShiftTime fromPreferredShift toID toShiftDay toShiftTime toPreferredShift;
shiftSwapRequestsDb = FirebaseDatabase.getInstance().getReference().child("Swap Requests").child("Shift Request")
.child(child);
swapRequestShift = new SwapRequestShift(toID,
toLoginID,
toImageUrl,
toName,
toPhone,
toEmail,
toCompanyBranch,
toAccount,
toShiftDate,
toShiftDay,
toShiftTime,
toPreferredShift,
fromID,
fromLoginID,
fromImageUrl,
fromName,
fromPhone,
fromEmail,
fromCompanyBranch,
fromAccount,
fromShiftDate,
fromShiftDay,
fromShiftTime,
fromPreferredShift,
-1,
-1);
shiftSwapRequestsDb.setValue(swapRequestShift)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
//set the request message
requestMessage = userName "" " wants to swap with your shift";
Map<String, Object> notificationMessage = new HashMap<>();
notificationMessage.put("message", requestMessage);
notificationMessage.put("from", currentUserId);
notificationDB.child(swapperID).push()
.setValue(notificationMessage).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
progressBar.setVisibility(View.INVISIBLE);
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(ProfileActivityShift.this, "Something went wrong", Toast.LENGTH_LONG).show();
Log.e(LOG_TAG, "Failed to insert row for " currentUserId);
}
});
Toast.makeText(ProfileActivityShift.this, "Notification sent", Toast.LENGTH_LONG).show();
progressBar_ShiftProfileChooseDialog.setVisibility(View.INVISIBLE);
listView.setVisibility(View.VISIBLE);
chooseShiftProfileDialog.dismiss();
shiftProfileDialog.dismiss();
progressBar.setVisibility(View.INVISIBLE);
textSentOrAcceptedRequest.setVisibility(View.VISIBLE);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(ProfileActivityShift.this, e.getMessage(), Toast.LENGTH_LONG).show();
progressBar_ShiftProfileChooseDialog.setVisibility(View.INVISIBLE);
listView.setVisibility(View.VISIBLE);
chooseShiftProfileDialog.dismiss();
shiftProfileDialog.dismiss();
progressBar.setVisibility(View.INVISIBLE);
buttonSwapRequest.setVisibility(View.VISIBLE);
}
});
}
});
}
Ответ №1:
попробуйте это
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.exists()) {
SwapDetails swapDetails = dataSnapshot.getValue(SwapDetails.class);
if (swapDetails.getSwapperID().equals(fromID)) {
swapBodyList.add(swapDetails);
shiftProfileAdapter.notifyItemInserted(swapBodyList.length - 1);
}
}
}
Комментарии:
1. Спасибо за ответ, но метод фактически не существует в адаптере shiftProfileAdapter.notifyItemInserted(swapBodyList.length — 1); в нем говорится: «Не удается разрешить метод «notifyItemInserted», а также длину, которая указана «Не удается разрешить длину символа»
2. затем вы можете использовать adapter.notifyDataSetChanged(), этот метод существует в adapter для List или RecyclerView
3. к сожалению, тоже не сработало, и список по-прежнему дублирует данные
Ответ №2:
Проблема решена. причина заключалась в том, что оператор if добавляет все данные в объект swapdetails, если он нашел идентификатор пользователя, затем он нашел другой и добавил их все снова и т.д.
итак, я просто создал bloolean внутри оператора if и заставил его принять значение true, если он нашел идентификатор подкачки, а затем использовать адаптер вне области действия addChildEventListene.
shiftSwapDb.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.exists()) {
SwapDetails swapDetails = dataSnapshot.getValue(SwapDetails.class);
if (swapDetails.getSwapperID().equals(fromID)) {
hasSwaperID = true;
}
}
}
shiftProfileAdapter.add(swapDetails);