0

so here is a simple voting page when I click the agree button, it loads the data of the agree on a value to int agree, and I make int agree2 = agree +1, then update it back to the field(so does disagree) It working good when I try it, the value of agreeing will keep plusing 1, but the problem is, when I reopen the app, clicking the agree button, its suppose to load the value in the field(if it's 7 last time, it needs to begin with 7), but it began with 1 every time I reopen and click it, anywhere of the code having trouble?

ps. THE MAIN problem is at button_agree

public class VotePage extends AppCompatActivity implements Serializable {
Button button_agree,button_disagree,button7;
TextView vote_title,vote_create,vote_start,vote_end,vote_content;
    FirebaseAuth firebaseAuth;
    FirebaseFirestore firebaseFirestore;
    String voteId;
    ListView lv2;
    int agree,agree2;
    int disagree,disagree2;

    ArrayList<item2> ar = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.votepage);
        button7 = findViewById(R.id.button7);
        button_agree = findViewById(R.id.button);
        button_disagree = findViewById(R.id.button22);
        vote_title = findViewById(R.id.textView7);
        vote_create = findViewById(R.id.textView8);
        vote_start = findViewById(R.id.textView9);
        vote_end = findViewById(R.id.textView10);
        vote_content = findViewById(R.id.textView11);
        lv2 = findViewById(R.id.lv2);
        firebaseAuth = FirebaseAuth.getInstance();
        firebaseFirestore = FirebaseFirestore.getInstance();

        if (savedInstanceState == null) {
            Bundle extras = getIntent().getExtras();
            if (extras == null) {
                voteId = null;
            } else {
                voteId = extras.getString("voteId");
            }
        } else {
            voteId = (String) savedInstanceState.getSerializable("voteId");
        }

        DocumentReference docRef = firebaseFirestore.collection("vote").document(voteId);
        docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                        Log.d("TAG", "DocumentSnapshot data: " + document.getData());
                        vote_title.setText(document.getString("vote_title"));
                        vote_create.setText(document.getString("createdBy"));
                        vote_start.setText(document.getString("start_time"));
                        vote_end.setText(document.getString("end_time"));
                        vote_content.setText(document.getString("vote_content"));
                        ar.add(new item2(document.getString("vote_title"), document.getString("vote_description")));
                    } else {
                        Log.d("TAG", "No such document");
                    }
                } else {
                    Log.d("TAG", "get failed with ", task.getException());
                }
                adapter3 adapter3 = new adapter3(getApplicationContext(), R.layout.list_row_convent, ar);
                adapter3.notifyDataSetChanged();
                lv2.setAdapter(adapter3);
            }
        });


        button7.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(VotePage.this, VoteMain.class));
            }
        });
        button_agree.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                AlertDialog.Builder builder1 = new AlertDialog.Builder(VotePage.this);
                builder1.setMessage("確定投下同意票嗎?一經投票不可更改.");
                builder1.setCancelable(true);

                builder1.setPositiveButton(
                        "Yes",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                                docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                                    @Override
                                    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                                        if (task.isSuccessful()) {
                                            DocumentSnapshot document = task.getResult();
                                            if (document.exists()) {
                                                Log.d("TAG", "DocumentSnapshot data: " + document.getData());
                                               agree = document.getLong("agree").intValue();


                                            } else {
                                                Log.d("TAG", "No such document");
                                            }
                                        } else {
                                            Log.d("TAG", "get failed with ", task.getException());
                                        }
                                    }
                                });
                                Map<String, Object> vote = new HashMap<>();
                                agree2 = agree +1;
                                vote.put("agree", agree2);

                                firebaseFirestore.collection("vote").document(voteId).update(vote).addOnCompleteListener(new OnCompleteListener<Void>() {
                                    @Override
                                    public void onComplete(@NonNull Task<Void> task) {
                                        if (task.isSuccessful()) {
                                            Toast.makeText(VotePage.this, "voted succesfully", Toast.LENGTH_LONG).show();


                                        }
                                    }
                                });
                            }
                        });

                builder1.setNegativeButton(
                        "No",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                            }
                        });

                AlertDialog alert11 = builder1.create();
                alert11.show();

            }

        });

the firestore field value,agree value will began at 1 everytime I reopen the app and click agree

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
neko12
  • 33
  • 5

1 Answers1

0

This is not the correct way to handle asynchronous operations. There is no way you can simply use the value of "agree" that you are getting inside the "onComplete()", outside the callback, because by the time you are using the following line of code:

agree2 = agree +1;

The data hasn't been finished loading yet from the database, hence that behavior of starting always from 1. To deal with such kind of situation, you should wait for the data. Firebase API is asynchronous. So please check my below answer to see how can you solve this using a custom callback:

If you want, you can also try using Android Architecture Components like LiveData and ViewModel.

Besides that, if you intend to use that voting mechanism in a multi-user environment, you should always consider the possibility that users can vote at the exact same moment. Meaning that you'll end up having inconsistent data. So for that, I recommend you using transactions as explained in my answer from the following posts:

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193