[Local Notifications Plugin] Invalid call of the 'OnNotificationReceived' client action

[Local Notifications Plugin] Invalid call of the 'OnNotificationReceived' client action

  
Forge Component
(5)
Published on 24 Jul by OutSystems R&D
5 votes
Published on 24 Jul by OutSystems R&D

Hi,

I've put notification block on layout block so it is to be present on all my pages and in my console I have multiple errors:

Invalid call of the 'OnNotificationReceived' client action of the 'MainFlow.MyScreenName' since the latter is not currently active. This is likely due to a platform's client action being used as an event handler or in a setTimeout function. Consider removing this call by using the 'On Destroy' event of the screen/block or moving your logic to a global client action.

How should I fix this?


Thank you.

Hey there, Mykola,

Just a quick check: are you using the latest platform version?

Best regards,

Carlos Simões

Hi Carlos.

Version 10.0.105.0

Hmmm, could you share your OnNotificationReceived flow, please?

Also, does the error occur on every screen access? Or after accessing multiple screens?

I've set notifications on one screen and then redirect to another where the error occurs one time. T.he script is in layout web block.

Hey again, Mykola,

I had a look and it looks like we might need to adjust the lifecycle of the plugin: apparently, there are callbacks bound to actions from a previous screen. We'll put an item on our backlog to revise this.

In the meantime, as a workaround, you can run this JavaScript on screen "OnDestroy" events to remove all callbacks:

(EDIT: bear in mind, this workaround should not work, according to answers below)
var listeners = ["trigger", "click"];
listeners.forEach(function(event){
    var callbacks = cordova.plugins.notification.local.core._listener[event];
    callbacks.forEach(function(callback){
        cordova.plugins.notification.local.un(event, callback);
    });
});


Does this work for you?

Carlos Simões

Carlos Simões wrote:

Hey again, Mykola,

I had a look and it looks like we might need to adjust the lifecycle of the plugin: apparently, there are callbacks bound to actions from a previous screen. We'll put an item on our backlog to revise this.

In the meantime, as a workaround, you can run this JavaScript on screen "OnDestroy" events to remove all callbacks:


var listeners = ["trigger", "click"];
listeners.forEach(function(event){
    var callbacks = cordova.plugins.notification.local.core._listener[event];
    callbacks.forEach(function(callback){
        cordova.plugins.notification.local.un(event, callback);
    });
});


Does this work for you?

Carlos Simões

Could you please give a status on this? I am not able to remove the callbacks with the  workaround specified above. As the NotificationEventsEmitter Block is included in the Layout block, every screen I navigate to will have the listeners registered and I will get many Actions triggered instead of one based on a click or trigger event.


Thanks.


Denis Mulder wrote:

Carlos Simões wrote:

Hey again, Mykola,

I had a look and it looks like we might need to adjust the lifecycle of the plugin: apparently, there are callbacks bound to actions from a previous screen. We'll put an item on our backlog to revise this.

In the meantime, as a workaround, you can run this JavaScript on screen "OnDestroy" events to remove all callbacks:


var listeners = ["trigger", "click"];
listeners.forEach(function(event){
    var callbacks = cordova.plugins.notification.local.core._listener[event];
    callbacks.forEach(function(callback){
        cordova.plugins.notification.local.un(event, callback);
    });
});


Does this work for you?

Carlos Simões

Could you please give a status on this? I am not able to remove the callbacks with the  workaround specified above. As the NotificationEventsEmitter Block is included in the Layout block, every screen I navigate to will have the listeners registered and I will get many Actions triggered instead of one based on a click or trigger event.


Thanks.


Hello, Dennis,

Hmm, the workaround should've worked, provided you assigned it to the OnDestroy event of the Layout or NotificationsEventEmitter plugin. Can you share if there's an error on the console when you navigate across screens?

Best regards,

Carlos Simões

Thanks for responding Carlos, I am breaking my brains over it. I have your code in the OnDestroy of the NotificationsEventEmitter block. I am not getting any errors in the console output. I did put a console.log statement in to make sure the OnDestroy gets fired and it does, as I see that in the console.

The listeners simply do not get removed using your code snippet.

Hello, Dennis,

After analyzing it a bit further, I realized I wasn't getting the proper callback object. But even then, it wasn't taking into account the fact that the block's "OnReady" would run before "OnDestroy" and would delete ALL handlers.

Here's the workaround adjusted accordingly:

(EDIT: bear in mind, this workaround should not work, according to answers below)

var listeners = ["trigger", "click"];
listeners.forEach(function(event){
    var callbacks = cordova.plugins.notification.local.core._listener[event];
    if(callbacks && callbacks.length > 0){
        // Remove only the first callback, since the block's OnReady runs before OnDestroy
        cordova.plugins.notification.local.un(event, callbacks[0][0]);
    }
});

I went ahead and tested this on a couple of scenarios, but could you please let us know if it solved it for you?

Best regards,

Carlos Simões

Hi Carlos,

Thanks again for helping out on this topic! 

Your new code snippet improved the working somewhat, but it is not fully working yet. 

Upon handling the received notification event while the app is in foreground, I navigate to a new screen.

I guess when transitioning between the old and new screens, with your snippet in place, there is a moment in time where both screens are active, the on Ready of the new screen has fired but the on Destroy of the old screen has not done its work removing the listeners yet. So I guess both screens receive the notification event and hence, I am getting two alert messages about the notification in my app (which is in the foreground when receiving the messages).

Then there is a second issue with this component in that the notification keeps firing after I received it in the foreground initially. In my handler of the NotificationReceived event, I clear the notification or otherwise it keeps on being detected and redirecting to the new screen (with a too many redirects as a consequence). But the clearing of the notification itself seems to refire the notification. I will report this issue in a separate support case.

I believe the local notification component should be overhauled as it uses an old version of the Cordova plugin with deprecated iOS classes. 

Hello, Denis,

Hmm, that's still not right...   There is indeed a period of time where two handlers may be up (as can be seen on the timeline here), so two notifications firing should be a matter of coincidence.

Well, I would usually point people towards opening up a support case for this to be analysed by the team, but I'm guessing you should already have one opened. In the meantime, please disregard the workaround.

As for updating the component, I will pass on feedback to the team.

Best regards,

Carlos Simões

I believe the solution would be to overhaul the component according to the online video "Off the electrical grid: Plug into Cordova". If you look at the video around 15:10 or so, you see the exact problem described. Other similar components, such as OneSignal fo remote notifications, follow these directions. The local notification component does not.

Unfortunately, I am not that experienced in programming, otherwise I would be more helpful, but hopefully, this can be part of a more comprehensive overhaul of the component, including getting it up to date with newer versions of the Cordova plugin.