0

I have a field in Firebase: balance. What I need is that after a person enters a sum 100, the field changes the value to 100. Then when the person enters a sum of 50, the field value becomes 150.

How do I write processing logic on the client? Summation of data. I think it is over-easy, but I need your help!

    mDatabaseUsers.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String user_id = mAuth.getCurrentUser().getUid();

            String balance = dataSnapshot.child(user_id).child("Balance").getValue(String.class);

            mCountPayment.setText(balance + " ₽");
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

    mPaymentButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            paymentIntent();
        }
    });
}

private void paymentIntent() {


    final String user_id = mAuth.getCurrentUser().getUid();

    final String count = mPaymentList.getText().toString().trim();

    if (!TextUtils.isEmpty(count)) {


        mDatabaseUsers.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                mDatabaseUsers.child(user_id).child("Balance").setValue(count);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
            }
        }
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Nikop
  • 11
  • 2
  • Are you using Cloud Firestore or Realtime Database? – CJR May 27 '19 at 10:24
  • Realtime Database – Nikop May 27 '19 at 10:30
  • You should look at this answer https://stackoverflow.com/a/40405392/3940445 by @FrankvanPuffelen who is part of the Firebase team. Like he said, you could use a sumation of data, eg, get the data, do the sumation client side, and upload it, but then there's risk of a race condition. If you know, by the way your application and firebase database is designed, that there will be no race condition, then the sumation method is OK to use. Otherwise, you should look at franks answer where he suggest you use a Transaction, which allows an atomic read&set data operation – CJR May 27 '19 at 11:05

1 Answers1

1

To write a value to the realtime database based on an existing value, you will need to use a transaction.

The basic code for your transaction will look like this:

DatabaseReference balanceRef = FirebaseDatabase.getInstance().getReference("/Users/"+ user_id +"/Balance");
Long delta = 50l;
balanceRef.runTransaction(new Transaction.Handler() {
    @Override
    public Transaction.Result doTransaction(MutableData mutableData) {
        Long balance = mutableData.getValue(Long.class);
        if (balance == null) {
            mutableData.setValue(delta);
        }
        else {
            Long amount = mutableData.getValue(Long.class);
            amount = amount + delta;
            mutableData.setValue(amount);
        }
        return Transaction.success(mutableData);
    }

    @Override
    public void onComplete(DatabaseError databaseError, boolean b,
                           DataSnapshot dataSnapshot) {
        // Transaction completed
        Log.d(TAG, "balanceTransaction:onComplete:" + databaseError);
    }
});
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807