Firebase Realtime Database Transaction

Viewed 315

I have been trying to run the transaction method but it fails to both get and set proper data in the Firebase Realtime Database.

Following is the code:

 private void receiveMoney() {
    String mobile=recipientText.getText().toString().trim();
    Double amount=Double.parseDouble(amountText.getText().toString().trim());
    mDatabase3=FirebaseDatabase.getInstance().getReference("account_details/Gn2eRixQQiTpvhX870n6nZp66tO2");
    mDatabase3.runTransaction(new Transaction.Handler() {

        @NonNull
        @Override
        public Transaction.Result doTransaction(@NonNull MutableData currentData) {

            Double newBalance=(double) currentData.child("initialBalance").getValue();
            System.out.println("Current Balance: "+newBalance+"  Amount: "+amount);

            currentData.setValue(newBalance);
            return Transaction.success(currentData);
        }

        @Override
        public void onComplete(@Nullable  DatabaseError error, boolean committed, @Nullable DataSnapshot currentData) {

        }
    });
}

Following is my database: Database Screenshot

Following is the error I get in the Run log:

E/RepoOperation: Caught Throwable.
java.lang.NullPointerException: Attempt to invoke virtual method 'double java.lang.Double.doubleValue()' on a null object reference
    at com.example.efikas.SendMoneyActivity$1.doTransaction(SendMoneyActivity.java:86)
    at com.google.firebase.database.core.Repo.startTransaction(Repo.java:933)
    at com.google.firebase.database.DatabaseReference$4.run(DatabaseReference.java:492)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
    at java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:784)

enter code here

2 Answers

To increment the value of initialBalance with the value of amount, there is no need to use any transaction. You can simply increment the value using the following lines of code:

DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference initialBalanceRef = db
    .child("account_details")
    .child("Gn2eRixQQiTpvhX870n6nZp66tO2")
    .child("initialBalance");
initialBalanceRef.setValue(ServerValue.increment(amount));

That's it. If you still want to use a transaction, please check my answer from the following post:

I think because you are using runTransaction and I think you should focus only 1 thing.

mDatabase3=FirebaseDatabase.getInstance().getReference("account_details/Gn2eRixQQiTpvhX870n6nZp66tO2/initialBalance");
mDatabase3.runTransaction(new Transaction.Handler() {

    @NonNull
    @Override
    public Transaction.Result doTransaction(@NonNull MutableData currentData) {
        if (currentData.getValue() == null) {
            currentData.setValue(0);
        } else {
            Double newBalance= (Double) currentData.getValue();
            System.out.println("Current Balance: "+newBalance+"  Amount: "+amount);

            currentData.setValue(newBalance);
        }
        

        return Transaction.success(currentData);
    }

    @Override
    public void onComplete(@Nullable  DatabaseError error, boolean committed, @Nullable DataSnapshot currentData) {

    }
});
Related