In the function apply of my Firestore transaction, I've written DocumentSnapshot snapshot = transaction.get(xyz); so that I get a reference to the document snapshot. I want to read one of it fields, but before I should check this field is contained (if(snapshot.contains("the field"))) and if it's not null (if(snapshot.getDouble("the field")) != null). Otherwise, I show an error message.

Also, I have written a validation message in the callback OnSuccess, which is triggered if the transaction could run (i.e.: if apply returned).

So both the error message and the validation message will be shown.

Below is an example:

FirebaseFirestore.getInstance().runTransaction(new Transaction.Function<Void>() {
                                    @Override
                                    public Void apply(@NonNull Transaction transaction) throws FirebaseFirestoreException {
                                        DocumentSnapshot snapshot = transaction.get(object_to_update);
                                        if(snapshot.contains("amount") && snapshot.getDouble("amount") != null) {
                                            double new_amount = snapshot.getDouble("amount") + seek_bar_value;
                                            transaction.update(object_to_update, "amount", new_amount);

                                        } else {

                                            Toast.makeText(context, "Error: Unable to find a required field to process the transaction correctly.", Toast.LENGTH_SHORT).show();
                                        }
                                        return null;
                                    }
                                }).addOnFailureListener(new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception e) {
                                        Toast.makeText(context, "Error: Unable to update the data.", Toast.LENGTH_SHORT).show();
                                    }
                                }).addOnSuccessListener(new OnSuccessListener<Void>() {
                                    @Override
                                    public void onSuccess(Void aVoid) {
                                        Toast.makeText(context, "Congratulations, the data has been updated.", Toast.LENGTH_SHORT).show();

So the problem is that the message "Error: Unable to find a required field to process the transaction correctly." and {the message "Congratulations, the data has been updated." or "Error: Unable to update the data."} will be both shown.

How could I fix this problem? Perhaps I could use a boolean in the callback OnSuccess to know if the apply's checks Contains and NotNull didn't show the error message, so that OnSuccess can show the validaton message, for example. But is there another way to solve the problem?

1 Answers

1
Doug Stevenson On Best Solutions

Perhaps I could use a boolean in the callback OnSuccess to know if the apply's checks Contains and NotNull didn't show the error message, so that OnSuccess can show the validaton message, for example. But is there another way to solve the problem?

You should read the documentation on passing information out of transactions. It gives you a pattern to use to determine if your transaction succeeded or failed. You should throw an exception out of your apply function in order to get the transaction to fail correctly. Right now, you are unconditionally returning null, which always means the transaction succeeded.