mk-5 / gdx-fireapp

libGDX Firebase API
Apache License 2.0
65 stars 21 forks source link

Cannot remove event listener for real-time database #39

Closed yabaza97 closed 3 years ago

yabaza97 commented 3 years ago

Describe the bug When I try to remove an event listener after getting the data that I want it does not get removed when cancel(); is called. I've tried calling cancel(); multiple times but it still doesn't work. I'm not sure if it's a bug or is there something I misunderstood.

To Reproduce

Here is how I call it

        GdxFIRDatabase.inst()
                .inReference("Rooms/")
                .onDataChange(Map.class)
                .then(new Consumer<Map>() {
                    @Override
                    public void accept(Map map) {
                        Gdx.app.log("test","onDataChangedCalled");
                    }
                });

And here is how I cancel it:

        GdxFIRDatabase.inst().inReference("Rooms/").onDataChange(Map.class).cancel();

Expected behavior It is supposed after cancel(); is called it is supposed on stopping logging "onDataChangedCalled" when the value changes but it doesn't.

Platform (please check one of the following): I've only tested it on android

Smartphone (please complete the following information only if platform is Android or iOS):

mk-5 commented 3 years ago

Thanks for reporting! I need to check it first, and I will let you know

yabaza97 commented 3 years ago

I found a work around I think, you can cancel it if you store the GdxFIRDatabase.inst().inReference("Rooms/").onDataChange(Map.class); as a ListenerPromise then use this variable to both call it and cancel it. Pretty much like in firebase where you store the reference and use it to add or remove events. So here is how I made it:

ListenerPromise<Map> Rooms;

Rooms = GdxFIRDatabase.inst().inReference("Rooms/").onDataChange(Map.class);

//To add the eventListener 
GdxFIRDatabase.promise()
           .then(Rooms)
           .then(new Consumer<Map>() {
               @Override
                public void accept(Map map) {
                   Gdx.app.log("test","onDataChangedCalled");
                }
            });

//To remove the eventListener 
Rooms.cancel();

That was the only I could make it work

mk-5 commented 3 years ago

@yabaza97 okay, so as a short answer. The references to listeners are not working in "static" context. You need to get the listener reference, and cancel it (if needed).

        ListenerPromise<Map> listener = GdxFIRDatabase.inst()
                .inReference("Rooms/")
                .onDataChange(Map.class)
                .thenListener(new Consumer<Map>() {
                    @Override
                    public void accept(Map map) {
                        Gdx.app.log("test","onDataChangedCalled");
                    }
                });

      listener.cancel();

You can use .then, but then you need to cast returned promise to ListenerPromise / ListenerPromise has .cancel method signature.

I will update WIKI page because there is no info about cancelling. What you already trying to achieve is also nice, maybe that would be a nice feature. The one problem I see here is a case when someone would like to have multiple listeners and cancel them independently.