Mohammad Ahsan
Mohammad Ahsan

Reputation: 60

RecyclerView items not getting removed

I'm using a RecyclerView to display a list of cards. On pressing a certain button on a card, the item associated with it is supposed to be removed from the database as well as the RecyclerView, therefore displaying a freshly updated RecyclerView with the remaining items.

Now the issue is that when I remove an item by pressing the button, the Firebase ValueListener is triggered and a fresh RecyclerView is to be generated, but instead, each of the remaining items is duplicated. This gives me a RecyclerView which has two of each item.

The ValueEventListener code block

usersRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            discoverPeopleList = new ArrayList<>();
            discoverPeopleRecyclerAdapter = new DiscoverPeopleRecyclerAdapter(getContext(), discoverPeopleList);
            discoverPeople.setAdapter(discoverPeopleRecyclerAdapter);

            for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                final java.lang.String
                        key = snapshot.getKey();
                DatabaseReference ref = database.getReference().child("users").child(key).child("followers");
                ref.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if (dataSnapshot.exists()){
                            boolean isBeingFollowed = false;
                            for (DataSnapshot ss : dataSnapshot.getChildren()){
                                if (ss.getKey().equals(mAuth.getCurrentUser().getUid())){
                                    isBeingFollowed = true;
                                }
                            }
                            if (!isBeingFollowed && !key.equals(mAuth.getCurrentUser().getUid())){
                                Log.v("Add", "One key added");
                                discoverPeopleList.add(key);
                                discoverPeopleRecyclerAdapter.notifyDataSetChanged();
                            }
                        }else if (!key.equals(mAuth.getCurrentUser().getUid())){
                            Log.v("Add", "One key added");
                            discoverPeopleList.add(key);
                            discoverPeopleRecyclerAdapter.notifyDataSetChanged();
                        }
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });
            }
            discoverPeopleProgressBar.setVisibility(View.GONE);
            discoverSessionsProgressBar.setVisibility(View.GONE);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

The OnClickListener code block in the adapter class(This is where the item is removed from the database)

holder.followBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (holder.followBtn.getText().equals("follow")){
                DatabaseReference followers = FirebaseDatabase.getInstance().getReference().child("users").child(userKey).child("followers");
                followers.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(FirebaseAuth.getInstance().getCurrentUser().getUid());

                FirebaseDatabase.getInstance().getReference().child("notificationRequests").child("username").setValue(userKey);
                FirebaseDatabase.getInstance().getReference().child("notificationRequests").child("message").setValue(FirebaseAuth.getInstance().getCurrentUser().getUid() + " followed you");

                DatabaseReference following = FirebaseDatabase.getInstance().getReference().child("users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("following");
                following.child(userKey).setValue(userKey);

                holder.followBtn.setText("following");
            }else{
                DatabaseReference followers = FirebaseDatabase.getInstance().getReference().child("users").child(userKey).child("followers");
                followers.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).removeValue();

                DatabaseReference following = FirebaseDatabase.getInstance().getReference().child("users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("following");
                following.child(userKey).removeValue();
                holder.followBtn.setText("follow");
            }
        }
    });

The Layout XML

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#303030"
tools:context="com.veloxima.sporthub.LiveDiscover">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
...

    <android.support.v7.widget.RecyclerView
        android:id="@+id/discover_people_recyclerVIew"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"></android.support.v7.widget.RecyclerView>
...
</LinearLayout>
</ScrollView>

Edit: I have confirmed that the ArrayList does indeed get cleared. The RecyclerView, on the other hand, is still messing up.

Upvotes: 0

Views: 114

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

When anything changes under usersRef, you'll get a complete new snapshot of the data under that location. So your code ends up adding all users (except for the one that was removed) to the discoverPeopleList again.

To stop this from happening, you'll need to clear discoverPeopleList before adding the new data:

public void onDataChange(DataSnapshot dataSnapshot) {
    if (dataSnapshot.exists()){
        boolean isBeingFollowed = false;
        discoverPeopleList.clear();
        for (DataSnapshot ss : dataSnapshot.getChildren()){
            if (ss.getKey().equals(mAuth.getCurrentUser().getUid())){
                isBeingFollowed = true;
            }
        }
        if (!isBeingFollowed && !key.equals(mAuth.getCurrentUser().getUid())){
            Log.v("Add", "One key added");
            discoverPeopleList.add(key);
            discoverPeopleRecyclerAdapter.notifyDataSetChanged();
        }
    }else if (!key.equals(mAuth.getCurrentUser().getUid())){
        Log.v("Add", "One key added");
        discoverPeopleList.add(key);
        discoverPeopleRecyclerAdapter.notifyDataSetChanged();
    }

This will work, but result in a complete redraw of the RecyclerView. To allow you to more granularly update the data, you should use addChildEventListener. This listener allows you to respond to individual child events, such as onChildAdded for adding users (including all the initial users) and onChildRemoved for removing them.

To see an example of such an adapter, see this code in the FirebaseUI library: https://github.com/firebase/FirebaseUI-Android/blob/master/database/src/main/java/com/firebase/ui/database/FirebaseRecyclerAdapter.java

Upvotes: 1

Related Questions