0

as the title. The OnCompleteListener will fire even when the child I remove does not exist. How can I prevent OnComplete (or OnSuccess ) fire when remove a not exist child ?

this is the code:

 ROOT_REF.child("111").removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
                   @Override
                   public void onComplete(@NonNull Task<Void> task) {
                       Log.d("SSSSSSSSSSSSSSSSSSSS","onComplete");
                   }
               });

note : the child "111" does not exist.

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • Can you please be more specific? What are you trying to achieve? – Alex Mamo May 06 '19 at 13:05
  • Actually these are the functions which gives you activity of an event like delete add update and create that these events are successfully done so whether the child exist or not it will always run if event is successfully done. – Kamran Ali May 06 '19 at 13:06
  • @KamranAli yep, but what I am trying to do is prevent the listeners fire when they " did not remove anything " – Trần Quốc Trung May 06 '19 at 13:09
  • @AlexMamo I am trying to prevent the listeners fire when they did not remove any thing from database. – Trần Quốc Trung May 06 '19 at 13:10
  • @TrầnQuốcTrung So you say that the listener is triggered even if the child `111`, does not exist, right? – Alex Mamo May 06 '19 at 13:11
  • 1
    you can do one thing , before setting a listener you can check if the child exist or not, `ROOT_REF.child("111").exist` firebase have functions to check for childs. – Kamran Ali May 06 '19 at 13:11
  • @AlexMamo yep, sir – Trần Quốc Trung May 06 '19 at 13:15
  • @TrầnQuốcTrung let me know if that works for you. – Kamran Ali May 06 '19 at 13:19
  • @KamranAli I checked before remove the value. but in my case, orther users can remove that value too. for example : when I dont have the connection, I check the child if it exist and make a request to remove that value ( the request will be queue ). some other users make the request to remove that value too ( but they have the connection and request is successful ). after that, I have the connection and my request sent to the DB. the OnSuccess will fire as normal. – Trần Quốc Trung May 06 '19 at 13:20
  • @TrầnQuốcTrung Why are I worried that `onComplete()` method is triggered? According to your last comment, since you are checking the existens of that child, why do you say that it's triggered? – Alex Mamo May 06 '19 at 13:24
  • @TrầnQuốcTrung it will trigger because it is the functionality of the function `onCompleteListener()` whether the exist or not it will trigger if the given work is successfully done. – Kamran Ali May 06 '19 at 13:31
  • @TrầnQuốcTrung and why are you doing any network request if you don't have internet connection. simply check internet if it is connected do your desired work if it is not show toast to user to connect to internet. – Kamran Ali May 06 '19 at 13:33
  • There is no way to change the behavior of the API. You will have to find a way to implement the behavior you want within the way the APIs work. For example: if you use a transaction, you can determine the new value of a node (including removing it), based on its existing value. – Frank van Puffelen May 06 '19 at 13:33
  • @AlexMamo "it will trigger even the child does not exist" -> this is the main problem. because I will do two different jobs ( child exist and does not exist ) – Trần Quốc Trung May 06 '19 at 13:35
  • @KamranAli "it will trigger even the child does not exist" -> this is the main problem. because I will do two different jobs ( child exist and does not exist ) – Trần Quốc Trung May 06 '19 at 13:35
  • @FrankvanPuffelen thanks Frank. I am trying to do that – Trần Quốc Trung May 06 '19 at 13:36
  • @KamranAli "why are you doing any network request if you don't have internet connection. simply check internet if it is connected do your desired work if it is not show toast to user to connect to internet." -> I always check the internet before do any single action in my app. but in case that the user's run out of cellular network data. the Receiver to check internet will not work – Trần Quốc Trung May 06 '19 at 13:38
  • @KamranAli note that the Receiver to check internet only work if you turn on/off the cellular or wifi. if you run out of data ( cellular data ) it will not work – Trần Quốc Trung May 06 '19 at 13:40
  • @TrầnQuốcTrung for checking internet use the google dns for ping to check if the internet is connected or not cuz in some scenerios you have the limited internet connection in that case you can use ping way for checking . – Kamran Ali May 06 '19 at 13:45
  • @KamranAli let my try.thanks – Trần Quốc Trung May 06 '19 at 13:47

1 Answers1

2

An onComplete listener fires when the state you set has been accomplished on the server. There is no way to change this behavior of the onComplete listener.

If you want to ensure that only a single user can remove a value, and that you know it is the current user, you should use a transaction. With a transaction you determine the new value of a node, based on its current value.

ROOT_REF.child("111").runTransaction(new Transaction.Handler() {
    @Override
    public Transaction.Result doTransaction(MutableData mutableData) {
        Object value = mutableData.getValue();
        if (value == null) {
            // Node doesn't exist
            return Transaction.success(mutableData);
        }

        // Remove value and report transaction success
        mutableData.setValue(null);
        return Transaction.success(mutableData);
    }

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

Note that:

  • A transaction's doTransaction method may fire multiple time, precisely when another user has modified the value already. For more on this, see Firebase runTransaction not working - MutableData is null.
  • Since transactions read the current value of the node, they only work when the user is online.
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807