user12427017
user12427017

Reputation:

Firebase Key's Child's data is overwritten to one on app restart or activity reopen

This piece of code runs correct. It increments the value by 1 but when i restart the app or relaunch the activity the data is overwritten to one.

int regEvents = 0;
String events_registered = "0";

private void btnAddRegisteredEvents() {
    final String key2 = FirebaseAuth.getInstance().getCurrentUser().getUid();

    final DatabaseReference databaseReferenceObj2 = FirebaseDatabase.getInstance()
            .getReference().child("Users")
            .child(key2).child("eventsregistered");
    databaseReferenceObj2.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            events_registered = dataSnapshot.getValue(String.class);
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
    regEvents = Integer.parseInt(events_registered) + 1;
    databaseReferenceObj2.setValue(String.valueOf(regEvents));


}

Upvotes: 0

Views: 52

Answers (2)

samthecodingman
samthecodingman

Reputation: 26171

This is because each time you start your app, you are initializing events_registered with a value of "0" and then immediately setting the value in your database to events_registered+1. The code contained within the event listener you defined is not executing before this set operation as it is asynchronous.

To increment a value stored in the database, it is best to use a transaction operation containing a transaction handler. This is a bundled read-modify-update operation useful for any operation that relies on the current database value such as incremental counters.

private void btnAddRegisteredEvents() {

    final String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();

    final DatabaseReference eventsRegisteredRef = FirebaseDatabase.getInstance()
        .getReference().child("Users")
        .child(userId).child("eventsregistered");

    eventsRegisteredRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            int eventsregistered = mutableData.getValue(Integer.class); // parses string as integer
            eventsregistered++;
            mutableData.setValue(eventsregistered);
            return Transaction.success(mutableData); // return updated data to be written
        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean b,
                               DataSnapshot dataSnapshot) {
            // Transaction completed
            Log.d(TAG, "postTransaction:onComplete:" + databaseError);
        }
    });
}

Upvotes: 1

Daya Nithi
Daya Nithi

Reputation: 117

This is because when you start the activity you are re-intializing events_registered variable value to 0 and it get's updated to that value. So here you just save that last incremented value in a shared preference or database. Next time when you launch the application. Just read the shared preference value and add shared preference value+1 to your value. That's all problem is solved. Now you will get the value updated correctly.

Upvotes: 0

Related Questions