java
java

Reputation: 13

How to increment number in firebase

I've edited the code. It works. It increment the counter in firebase. But there is 1 problem. Whenever I restart the app (after clear recent app), the increment starts over. It does not continue from previous number.

public class MainActivity extends AppCompatActivity {

Button bNext;
long count;

DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference mCounterRef = mRootRef.child("counter");

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

    bNext = (Button) findViewById(R.id.bNext);

    bNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mCounterRef.setValue(++count);
        }
    });

}
}

this is my database

Upvotes: 1

Views: 4950

Answers (1)

Bob Snyder
Bob Snyder

Reputation: 38309

Three things require fixing:

  1. count in your DB is a number and will be read as a Long. You cannot cast directly to int. Instead you can cast to a long, or you could use two casts: int count = (int)(long) ...
  2. You are using the post-increment operator. It adds one after using the value. Use pre-increment instead.
  3. Listen for a single change, otherwise you will loop, because setValue() will cause the listener for fire again, and again, etc.

As Frank notes, a Transaction is the better way to safely modify counters.

    final DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
    final DatabaseReference mCounterRef = mRootRef.child("counter");
    // listen for single change
    mCounterRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            // getValue() returns Long
            long count = (long) dataSnapshot.child("count").getValue();

            System.out.println("count before setValue()=" + count);

            mCounterRef.child("count").setValue(++count);  // <= Change to ++count

            System.out.println("count after setValue()=" + count);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            // throw an error if setValue() is rejected
            throw databaseError.toException();
        }
    });

Update for edited question:

You probably need to update your security rules to allow write access. Add a completion listener to see if setValue() is failing:

mCounterRef.child("count").setValue(++count, new DatabaseReference.CompletionListener() {
    @Override
    public void onComplete(DatabaseError databaseError,
                           DatabaseReference databaseReference) {
        if (databaseError != null) {
            System.out.println("Error: " + databaseError.getMessage());
        }
    }
});

Upvotes: 3

Related Questions