Sean
Sean

Reputation: 13

Increment values in firebase realtime

There can be mutiple people on the app click a button that will Increment value in firebase and get that value back, but if each person clicks the button at the same time right now, they will get the same value, how do I Increment with each person getting a differnt value?

     DatabaseReference reference = FirebaseDatabase.getInstance().getReference("queue");
    reference.child(queue_id).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            currentNum = (long) dataSnapshot.child("currentNumber").getValue();
            ++currentNum;
            dataSnapshot.child("currentNumber").getRef().setValue(++currentNum);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

Upvotes: 1

Views: 161

Answers (3)

Frank van Puffelen
Frank van Puffelen

Reputation: 600006

To prevent conflicts from multiple users updating the same node at (almost) the same time, you need to use a transaction. In your case that'd look something like:

DatabaseReference reference = FirebaseDatabase.getInstance().getReference("queue");
DatabaseReference numberRef = reference.child(queue_id).child("currentNumber");

numberRef.runTransaction(new Transaction.Handler() {
    @Override
    public Transaction.Result doTransaction(MutableData mutableData) {
        Long value = mutableData.getValue(Long.class);
        if (value == null) {
            mutableData.setValue(1);
        }
        else {
            mutableData.setValue(value+1);
        }
        return Transaction.success(mutableData);
    }
}

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

Upvotes: 2

Ticherhaz FreePalestine
Ticherhaz FreePalestine

Reputation: 2387

You can use method transactions. Refer to this link: https://firebase.google.com/docs/database/android/read-and-write#save_data_as_transactions"

private void onStarClicked(DatabaseReference postRef) {
    postRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            Post p = mutableData.getValue(Post.class);
            if (p == null) {
                return Transaction.success(mutableData);
            }
        if (p.stars.containsKey(getUid())) {
            // Unstar the post and remove self from stars
            p.starCount = p.starCount - 1;
            p.stars.remove(getUid());
        } else {
            // Star the post and add self to stars
            p.starCount = p.starCount + 1;
            p.stars.put(getUid(), true);
        }

        // Set value and report transaction success
        mutableData.setValue(p);
        return Transaction.success(mutableData);
    }

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

Upvotes: 0

mayur
mayur

Reputation: 384

As per your code, you're incrementing the counter by 1 but you are not posting the same in the database. Use HashMap to update the data in your database when you modify it. You can try the below code:

    button.setOnClickListerner(new View.onClickListener() {
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("queue");
    reference.child(queue_id).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            currentNum = (long) dataSnapshot.child("currentNumber").getValue();
            long newValue = currentNum + 1;
            HasMap<String, Object> hashMap = new HashMap<>();
            hashMap.put ("currentNumber", newValue);
            reference.child(queue_id).updateChildren(hashMap);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
};

Hope this works!

Upvotes: 0

Related Questions