3

I am creating an app in which points increases on button click and those points should be saved to firebase. I managed to save those data to firebase. But when I destroy my app and open it again the points value is showing same but after clicking button. It again starts from 0.

For example: every time on button click the points value increases to 10 points. Now when I completely destroy the app and open it again, the points value shows same, but when button clicked it again starts from initial condition.

Here is my code

    int amount = 0;

@Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);

button_claim.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            amount = amount + 100;


            textView_points.setText(String.valueOf(amount));
            databaseReference.setValue(textView_points.getText().toString());

        }
    });


}


@Override
    protected void onStart() {
    super.onStart();
    if (mAuth.getCurrentUser() == null) {
        finish();
        Intent main = new Intent(this,MainActivity.class);
        main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(main);
    }

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

            textView_points.setText(dataSnapshot.getValue(String.class));
            databaseReference.setValue(textView_points.getText().toString());
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

            Toast.makeText(Main2Activity.this,"error",Toast.LENGTH_LONG).show();
        }
    });



    }

Before destroying the app see the image please, points increasing on button click before destroying the app and uploading to database please see image 1

Opened app again(after closing) it is showing the same updated point please see image 2

Now when i click claim it returns back to 100 please see image number 3

please help me on this problem, and i am a newbie Thanks

Hash
  • 147
  • 1
  • 4
  • 14

3 Answers3

7

Edit: 29th, June 2020

Now it's also possible to solve this problem without the use of a transaction. We can simply increment a value using:

rootRef.child("score").setValue(ServerValue.increment(1));

And for decremenet, the following line of code is required:

rootRef.child("score").setValue(ServerValue.increment(-1));

This is how you set a value in your Firebase database:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("score").setValue(1);

Assuming that the your score field is of type Integer, to solve this, please use the following method:

public static void setScore(String operation) {
    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference scoreRef = rootRef.child("score");
    scoreRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            Integer score = mutableData.getValue(Integer.class);
            if (score == null) {
                return Transaction.success(mutableData);
            }

            if (operation.equals("increaseScore")) {
                mutableData.setValue(score + 1);
            } else if (operation.equals("decreaseScore")){
                mutableData.setValue(score - 1);
            }

            return Transaction.success(mutableData);
        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {}
    });
}

For this, I recommend you definitely use transactions. You will avoid wrong results if users are trying to increase/decrease the score in the same time. So as a conclusion, call this method accordingly to your increase/decrease operation.

This is how you can read it:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference scoreRef = rootRef.child("score");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Integer score = ds.getValue(Integer.class);
        Log.d("TAG", score + "");
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
scoreRef.addListenerForSingleValueEvent(eventListener);
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • sorry but i am very new to this so dont know much about above code please see above code i have given – Hash Jan 18 '18 at 15:49
  • 1
    Have you tried my code? [Here](https://firebase.google.com/docs/database/android/read-and-write#save_data_as_transactions) you can find everything about Firebase transaction. Give it a try, will work. – Alex Mamo Jan 18 '18 at 15:51
  • yes i tried by removing advalueremoving method from my code but not working(i added your code but dont know why it is not working) – Hash Jan 18 '18 at 15:54
  • no errors but nothing is shown on textview nor saving to firebase or i think i am implementing it in wrong way – Hash Jan 18 '18 at 16:26
  • hey i managed to update value with your code it is working but again the same problem when i destroy app again it comes to initial – Hash Jan 18 '18 at 20:12
  • Glad to hear that you make it work. Move the logic inside the `onCreate` method. – Alex Mamo Jan 19 '18 at 09:45
  • I have alrdy done that but not working, can you tell me how can I set a key value in firebase and retrieve it to my app and update its value from app? Thanks – Hash Jan 21 '18 at 08:34
  • thanks above method that is addvalue for singleevent worked for me – Hash Jan 23 '18 at 07:01
0

You need to first get the value of previous score and then add it with the current score and then update the final value in the firebase database.

question_score.child("score").addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            String previousScore = dataSnapshot.getValue(String.class);
                            if (previousScore!=null){
                                int finalScore = Integer.parseInt(previousScore) + current_score;
                                question_score.child("score").setValue(String.valueOf(finalScore));
                            }
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });
DHANANJAY KUMAR
  • 86
  • 1
  • 13
  • Thanks please see my code and tell me some idea to implement in correct way , the code you gave is not working for me or i think i am doing something wrong – Hash Jan 18 '18 at 15:50
0

I think that previous score is a string in you code @DHANANJAY KUMAR and Strings cannot be added and also what is the meaning of String.class. I think It can be made

int previousScore = dataSnapshot.getValue(Integer.class);

if we can edit

String.class

to

Integer.class

or

int.class

Please Clarify

vimuth
  • 5,064
  • 33
  • 79
  • 116