Fetching specific key from firebase using recyclerview adapter in android studio

Ngugi Kariuki :

I'm creating a voting application.I have a Firebase Realtime Database that contains the candidates to be voted for as below: firebase database

I am also using a RecyclerView to fetch all the candidates and display them in a CardView as below:

Fetched data from the database

The goal here is that everytime I click on the vote button, it should go to the firebase database, fetch the unique key of the selected candidate, and cast a vote. I currently can vote, but the key is hard coded in the adapter inside the updatetotalVotes() method. Let me share the code:

public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.cardview, parent, false));
    }
    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
        holder.name.setText(candidates.get(position).getFirstname());
        holder.party.setText(candidates.get(position).getParty());
        holder.category.setText(candidates.get(position).getCategory());
        Picasso.get().load(candidates.get(position).getImageurl()).into(holder.profilepic);

        holder.vote.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateTotalVotes("increaseTotalVotes");
            }
        });

    }

    public static void updateTotalVotes(final String operation) {
        System.out.println("Inside updateTotalVotes");
        DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();

        DatabaseReference totalVotesRef = rootRef.child("candidates").child("-M3CHX1qYFobyO65qhc8").child("totalVotes");
        totalVotesRef.runTransaction(new Transaction.Handler() {
            @Override
            public Transaction.Result doTransaction(MutableData mutableData) {
                System.out.println("Inside Transactions");
                Integer votes = mutableData.getValue(Integer.class);
                if (votes == null) {
                    System.out.println("Inside first if statement = null");
                    return Transaction.success(mutableData);
                }

                if (operation.equals("increaseTotalVotes")) {
                    System.out.println("Inside update Votes by adding 1");
                    mutableData.setValue(votes + 1);
                } else if (operation.equals("decreaseTotalVotes")){
                    mutableData.setValue(votes - 1);
                }

                return Transaction.success(mutableData);
            }

            @Override
            public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
               // Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
            }
        });
    }

    @Override
    public int getItemCount() {
        return candidates.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder{

        TextView name, party, category;
        ImageView profilepic;
        Button vote;

        public MyViewHolder(View itemView) {
            super(itemView);
            name = (TextView) itemView.findViewById(R.id.name);
            party = (TextView) itemView.findViewById(R.id.party);
            profilepic = (ImageView) itemView.findViewById(R.id.profilepic);
            category = (TextView) itemView.findViewById(R.id.category);
            vote = (Button) itemView.findViewById(R.id.vote);
        }

    }

Is there a way to dynamically fetch the candidate unique key from the database and save it in a variable instead of hard coding it? Thanks.

Alex Mamo :

To solve this, you need to change that method to:

public static void updateTotalVotes(final String operation, String key) {
    System.out.println("Inside updateTotalVotes");
    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();

    DatabaseReference totalVotesRef = rootRef.child("candidates").child(key).child("totalVotes");
    totalVotesRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            System.out.println("Inside Transactions");
            Integer votes = mutableData.getValue(Integer.class);
            if (votes == null) {
                System.out.println("Inside first if statement = null");
                return Transaction.success(mutableData);
            }

            if (operation.equals("increaseTotalVotes")) {
                System.out.println("Inside update Votes by adding 1");
                mutableData.setValue(votes + 1);
            } else if (operation.equals("decreaseTotalVotes")){
                mutableData.setValue(votes - 1);
            }

            return Transaction.success(mutableData);
        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
            // Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
        }
    });
}

And inside onClick() kick it off using:

updateTotalVotes("increaseTotalVotes", candidates.get(position).getImageurl());

As I see in your screenshot that imageurl contains the desired key. I recommend you to add also a key property that should hold the exact key of every object and not use imageurl as above.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=371666&siteId=1