[OneSignal Plugin] Deeplink to specific screen with parameter

[OneSignal Plugin] Deeplink to specific screen with parameter

  
Forge Component
(5)
Published on 23 Nov (4 weeks ago) by OutSystems R&D
5 votes
Published on 23 Nov (4 weeks ago) by OutSystems R&D

In the SendPushNotification is a parameter Deeplink; how can i use this parameter to redirect to a specific screen (with parameter) when the notification is clicked?

To be more specific:

Server side:

- I added a PushNotificationDeepLink to the SendPushNotification with parameter key / value pair (task / 1)

App side:

- I added the OneSignal widget to the Layout with a OnNotificaitonOpened / OnNotificationReceived Event Handler


When i send a notification and open it; these events are not triggered? Did I miss something?


I am having exactly the same issue

Also, having a deep link or not makes no difference, the triggers wont work either way

Cipriano Teibão wrote:

Also, having a deep link or not makes no difference, the triggers wont work either way

That's my conclusion too


Created a support case for this issue

Hey, guys,

I have been tackling this case with Matthias and have replied on another thread, concerning the events not triggering.

If you're experiencing that specific problem, would you please let me know if this solved it for you?

Best regards,

Carlos Simões

So every time a screen loads the app calls the Register action? That doesn't seem optimized at all...


From what I could find, what is hapenning is that the event listeners for some reason are lost, if you add the event listeners it works fine. I do not know if this is the right solution, but it is working fine so far.


1- Create a new action on the plugin eSpace.

2- Place the following code in that action:


require(["OneSignalPluginManager"], function(oneSignalMgr){
   
    var builder = window.plugins.OneSignal.startInit($parameters.ApiKey);
    builder.handleNotificationReceived(oneSignalMgr.notificationReceivedDelegate);
    builder.handleNotificationOpened(oneSignalMgr.notificationOpenedDelegate);
    builder.inFocusDisplaying($parameters.InFocusDisplayOption);
   
    // Set your iOS Settings
    var iosSettings = {};
    iosSettings["kOSSettingsKeyAutoPrompt"] = true;
    iosSettings["kOSSettingsKeyInAppLaunchURL"] = false;
   
    builder.iOSSettings(iosSettings);
   
    builder.endInit();
   
    $resolve();
   
});


3- Use the new action on the onready event of the layout block.


https://www.screencast.com/t/eU0KI7H5


Should work just fine.


PS: Only tested on Android

Cipriano Teibão wrote:

2- Place the following code in that action:


require(["OneSignalPluginManager"], function(oneSignalMgr){
   
    var builder = window.plugins.OneSignal.startInit($parameters.ApiKey);
    builder.handleNotificationReceived(oneSignalMgr.notificationReceivedDelegate);
    builder.handleNotificationOpened(oneSignalMgr.notificationOpenedDelegate);
    builder.inFocusDisplaying($parameters.InFocusDisplayOption);
   
    // Set your iOS Settings
    var iosSettings = {};
    iosSettings["kOSSettingsKeyAutoPrompt"] = true;
    iosSettings["kOSSettingsKeyInAppLaunchURL"] = false;
   
    builder.iOSSettings(iosSettings);
   
    builder.endInit();
   
    $resolve();
   
});


Hi Cipriano,

Your solution looks promising so I tried to implement it. However I get stuck on the two parameters the JavaScript requires: ApiKey and InFocusDisplayOption. Which data types should these be and which values should be used?

Hope you can help me take the next step.

Thanks!

Frans Moquette



Hi,


1 - Your onesignal ApiKey.

2 - Its a value from the static entity 'InFocusDisplayOption' we have it as NOTIFICATION


Regards,

Cipriano

Cipriano Teibão wrote:

1 - Your onesignal ApiKey.

2 - Its a value from the static entity 'InFocusDisplayOption' we have it as NOTIFICATION

Hi Cipriano,

Thanks. I got my app to compile and I thought your solution worked, because I had the OnNotificationReceived event triggered. But alas, it was triggered only once! On all subsequent push messages nothing happened like before. I tried some variations and discovered something really weird: a push notification will trigger the OnNotificationReceived event exactly once after the app has been recompiled and updated to the latest version on the mobile device. Any subsequent notifications do not trigger the events.

So what is wrong? I created a Client Action in the OneSignal plugin exactly by your example with input parameters ApiKey and InfocusDisplayOption. The client action is called from OnReady of the Layout block with the parameters properly filled. The Layout block also contains the OneSignal plugin in a container and the OnNotificationReceived and OnNotificationOpened event handlers. The Layout block is used for every screen in the mobile app.

Any suggestions on what I could do different?



Hi Everyone,

Outsystems provided me with what they call a 'temporary workaround' that works for us. Their workaround is as follows.

"I think I found something which may explain the behavior. Allow me to explain:

  1. The OneSignal block's Destroy handler removes the Received and Opened event handlers when it runs;
  2. This is done because Client actions from the block are called when handling these events; but after a transition to a new screen, actions from the previous screen can't be called anymore (doing so will trigger an error on the console/Service Center stating so);
  3. Unfortunately, the Destroy event is triggered after the next screen's Ready event, meaning EVERY plugin event handler will be lost (see this link for a clear timeline of screen lifecycle events).

We are currently discussing what is the best way to solve this, but in the meantime, what I propose as a temporary workaround is that the Destroy event handler be disabled from the OneSignal block.


Allow me to reiterate the steps, now including this temporary workaround:

  1. Place the 'OneSignal' block on the 'Layout', under the 'layout' container; I believe you have done this as the screenshot clearly depicts it;
  2. Make sure the handler of the 'Ready' event calls either 'Register' or 'RegisterWithUser' actions, in addition to other existing calls; I didn't mention this step explicitly in my last communication, but since the device is receiving notifications, you should already be doing it;
  3. Open the 'OneSignalPlugin' module, select the 'OneSignal' block and choose '(None)' as its 'OnDestroy' handler, as depicted on ; don't forget to publish the module and refresh the references of the consuming app."


The actual solution for us was step 3, the other things were already in place in one way or another.

Hope this info is useful for others with the same problem.


Hi Frans,

Thank you for step-by-step instruction for solving this issue. However I'm still having errors on console when notification is received or clicked:

Controller [2017-07-18T13:37:09.627Z]: Invalid call of the 'OnNotificationReceived' client action of the 'MainFlow.HomePage' 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.
undefined.


Hello, Mykola,

Looking at the proposed solution, I believe this is a side-effect of the workaround: since we are removing the logic that removes the event handlers, if you navigate to a screen that doesn't include the 'OneSignal' block, it will try to call the previous screen's handlers (and trigger this error).

As long as you use the OneSignal block on all screens for the moment, the handlers will be re-set and the error will not be triggered.

If you do feel something is up, however, please do let us know!

Best regards,

Carlo Simões

I edited the build Deeplink action in the API module to include a new input parameter which is a "PageName" and then amend the logic to add this too the DeepLink variable.  You will then get something along the lines of com.outsystems.appname/AppName/PageName.  Without making this change I was getting errors too.

Dan

Hi Everyone,

We have (finally) been able to create a working solution with the OneSignal plugin using Cipriano Teibão's solution. One important thing, the Javascript parameter called 'ApiKey' is improperly named, it should have been named 'OneSignalAppId' and the value of your OneSignalAppId should be passed into the action.

Because of the name for this parameter we initially used the OneSignalRestApiKey-value in our call to this action and our app did not work on Android (phones would not stay subscribed with OneSignal). The issue only presented itself with Android phones, iOS phones worked perfectly fine from the start. It took us many weeks and the help of Outsystems support (thanks again Carlo Simões) to discover that the OneSignalAppId-value had to be passed into the action instead.

Hopes this helps anyone still having issues implementing the OneSignal plugin.

Frans

The latest version of the component the EventHandlers are working fine now; does anyone now how to:

  • Create a DeepLink in the SendPushNotification(ToTag)?
  • Take action on this Deeplink in the EventHandlers?


Matthias

Hello, Matthias and everyone,

Just a quick note that we are planning on having a look at deeplinks for the plugin, so make extra sure it's bullet proof.

For the time being, if this is affecting your work, could you guys get in touch with us via a support case, so we can better prioritize?

Best regards,

Carlos Simões

Hello Carlos,


To be honest currently I'm just interpreting the Raw Payload until this gets fixed : )

 The Deeplink always comes empty if I send it as a application screen. Only works for webpages. Either through your API or through dashboard of OneSignal. I guess its on the receiving part the issue.


Regards

From my initial analysis, the problem seems related with a mismatch between a received JSON option and the corresponding structure attribute.

We didn't have a proposed workaround at the moment, but using the RAW payload seems like something you can work with.

If that changes, could you get in touch with us via Support Portal?

Thanks, and best regards,

Carlos Simões

Hi Carlos.

I'm trying to get my app opened (specific screen) when I click the push message.

I was doing that following the article https://success.outsystems.com/Documentation/Development_FAQs/How_to_Define_Mobile_App_Deep_Links

But it is not working.

Could you please give me an example how to use RAW payload with OneSignal, so I can do it myself.

Thanks in advance.

Luciano Guimaraes

Hello, Luciano,

I'd say you have to change the plugin's "SendPushNotification" actions to have an additional "RawData" parameter and assign it to the "RawPayload" attribute (see here).

Then, make sure that when you handle the "NotificationOpened" and "NotificationReceived" events, you look for the "RawPayload" parameter and act accordingly.

Makes sense?

Best regards,

Carlos Simões

I'll give a try on it.

Thanks a lot.

Luciano Guimaraes

Hello Luciano,

I didn't change the plugin and was able to get the rawdata, then I read it and redirected to the screen I needed.

However this approach doesn't seem to be working if the application is off.

Best regards

Hi Cristiano.

I'm able to get it working fine.

The RawData is coming on Notification events (received / opened)  - thanks to Carlos - and I wrote a very simple parse to extract the content I need to redirect to the specified screen. No need to change the plugin indeed.

I notice the application has to register to OneSignal service (in my case RegisterWithUser action) every time it is initialized. This way, push notifications are received with no problems.

Cheers

Luciano

Hello, Luciano,

Glad to hear you got it to work! And without changing the plugin you get to keep the upgrade capabilities intact!

I heard that there were a couple of new releases for the plugin, focusing on fixing and improving deeplinks, namely adding the ability to specify a screen.

Please test it and let us know if everything's working!

Best regards,

Carlos Simões

Hi Carlos. I've updated the OneSignal plugin and could see deeplinks are now working great!

I did not have time to do a refactoring on my code yet (RawPayload to Deeplinks) but I'm satisfied now with this plugin last version.

Thanks again.

Luciano

i can now receive the Deeplink in the Notification/Payload/LaunchURL so it's working now; But how can i redirect to this URL? There is no Destination widget with a dynamic URL.

Hey, Matthias,

Well, from my understanding, if the app is closed, when it's opened, it will redirect automatically to the provided screen, with the provided input parameters.

When the app is opened, I think this doesn't happen automatically (to allow the developer to control this behavior), but you will have access to a deeplink structure, which includes a 'Screen' attribute. You can then use a Switch-based action to redirect to the target screens.

If you REALLY want this navigation to be dynamic, you can use the platform's Navigation JS API. You can provide the URL itself or only use the screen (as per the documentation).

Does this work for you?

Best regards,

Carlos Simões

Hi Carlos.

I'm curious now... You said Outsystems opens the correct screen sent in deeplink params when app is closed. How can I achieve that ? What is the deeplink format to achieve that ?

Can you show us an example ?

I did that on app main screen but I'm getting some strange behavious. I think this Outsystems way could fix it.

Cheers

Luciano Guimaraes

Hello, Luciano,

Sorry for the late reply. Well, I'd say simply fill in the structure below and you should be good to go:

The latest released version has this structure and the fields are self-explanatory, so I'm guessing you have another issue where the deeplinks are not properly redirecting. Are you testing with iOS?

Best regards,

Carlos Simões

Hi Carlos.

I'm testing with Android following the instructions in https://success.outsystems.com/Documentation/Development_FAQs/How_to_Define_Mobile_App_Deep_Links

Unfortunately, it is not working and I think I missed something out... Is there anything else to do ?

Cheers.

Luciano Guimaraes

Hmm, now that you mentioned that article, I'm not sure what you're trying to achieve. Are you trying to get a deeplink to work using a Link widget on your UI? Or are you trying to get your notification to open the app using a deeplink?

If we're talking about the first scenario: yes, that article is correct! You need to build a URL that matches the example.

If you're talking about the second scenario, you might have caught an older version of Silk UI Mobile, which had a slightly different Splash screen logic, preventing the redirects. 

If you're having trouble getting deeplinks to work, could you check if your Splash screen's 'OnLoadComplete' client action logic looks like the one on the image below?

If not, the best way to get it to work would be to make sure Silk UI Mobile is upgraded to the latest version and create a new mobile application. Then copy the 'OnLoadComplete' action from its Splash screen to your own Splash screen. Publish and test it.

Please let us know how things went! :)

Best regards,

Carlos Simões

Hello Carlos,


We updated to latest version and deeplinks seem to be working perfectly without reading the RawPayload : )

Thanks for the update!

Best regards,

Cristiano Marques

Hi Carlos.

I'm trying to archive the second one. So, when user hit the push notification, the app should be opened on a specific screen.

I checked my app and the SilkUI is updated with the code you mentioned.

My question is how to build the oneSignal message. What are the values for the Deeplink.Schema, DeepLink.Application and DeepLink.Params. So I was guessing that article could help but not.

Could you give some examples for the DeepLink values I have to use to make this work ?

Thanks again.

Luciano Guimaraes

Luciano Guimaraes wrote:

Hi Carlos.

I'm trying to archive the second one. So, when user hit the push notification, the app should be opened on a specific screen.

I checked my app and the SilkUI is updated with the code you mentioned.

My question is how to build the oneSignal message. What are the values for the Deeplink.Schema, DeepLink.Application and DeepLink.Params. So I was guessing that article could help but not.

Could you give some examples for the DeepLink values I have to use to make this work ?

Thanks again.

Luciano Guimaraes

Well, in my case:

  1. "Schema" maps to the application identifier of my app with the protocol suffix (i.e. "com.outsystemscloud.carlossimoes.OSSample://");
  2. "Application" maps to the main module of the application (i.e. "OneSignalSampleApp"); be careful not to use the application's name here;
  3. "TargetScreen" maps to the screen name you are targeting (i.e. "TestScreen");
  4. Finally, for "Parameters" you're you going to first need to specify the Name (named "Key" on the structure) and Value of each input parameter, and then use ListAppend to add it to the structure attribute.

Following the article, nearly each of these attributes will fit, but I do admit that the "<YourApp>" part might be error inducing. I have sent some feedback for the team to look into it!

Please let us know if with these instructions you are able to send a deeplinked notification!

Best regards,

Hi Carlos, almost there!

I followed your instructions, I was misspelling the "Application" - you're right.

But, I could not find an attribute for the "TargetScreen". So, I filled the " Application"  up to "Application/TargetScreen".

This makes the app to be opened and redirect to the follow URL https://lucianodltec.outsystemscloud.com/BeeMakesMobile/PropostaDetail/?ChamadoId=572&Prestador=True&PropostaId=0

At this step, the app shows a redirect error page. I think it is because the " / " just before the " ? " character in URL. Or it may be an server URL instead a local file android URL.

Bellow, it's showing the app error screen.


Just below, it is how I'm building the oneSignal message.


Regards,

Luciano Guimaraes

Sending images again... 


Hello, Luciano,

I was hoping to have the charm on third attempt...but at least I think I know what's up.


Are you sure you upgraded the OneSignal Plugin to the latest version? Version 1.0.6 was the one that added the "TargetScreen" parameter.

If so, have you refreshed the references on the module that sends the notifications? This way the new structure definition will be fetched.

Best regards,

Carlos Simões

Hi Carlos, thanks for your patience.


We move on and now the target screen is being opened :-)

I'm following the OneSignal but I didn't receive the update notification... sorry.


Now I'm in trouble at two points:

1) the screen is correctly opened only when the app is already loaded (even in background). when the app is closed, the screen is loaded but without its parameters.

2) the target screen redirect produces a complete "refresh" of the app, this cause a bad user experience and is taking longer than a simple screen transition. Is there  another way to to it ?


I again thank you really much for your dedication helping me.

Seeya

Luciano Guimaraes

Alright, I feel we're getting close!

From my testing, the OneSignal plugin doesn't redirect to the target screen if the app is already opened: you must catch the "OnNotificationOpened" event, read the notification sent with it and perform the redirect with your logic (I described the general lines on how to do it for Matthias, in a post above). This makes sense: if we always redirected, we would impose this behavior on people who didn't want to redirect when the app was opened.

Is it possible that you already have some logic attached to this event that might be triggered on both scenarios? If so, can you use the client-side debugger to find out if it's involved? (set a breakpoint on both that logic and on the 'OnLoadComplete')

Also, if you could record the refresh behavior, that would be great, as well.

Best regards,

Carlos Simões

Hi Carlos.

I recorded the push notification being opened on two devices. 

Please, watch on https://youtu.be/UZ7GSfuPHug

The above device has the app already opened. The below device has the app closed. 

Some strange things:

1) The deeplink parameters are now working, but I did not make any change on it. I'm happy with this :-)

2) The above device shows the app being redirected to the correct screen, but I did'nt anything to handle it... it is done "automagically"

3) The above device shows the app reload I mentioned before. So the process is slow and the bigger problem, the app loses its screen stack and a back button hit closes it instead of returning to the previous screen.

I agree with you... when the app is opened, I should handle the opened event to do what I want.

Cheers

Luciano Guimaraes

Hello, Luciano,

Alright, I think I understand what's up: on the top device (the one with the app opened), you receive a "native" notification on your drawer. Clicking on this notification will always open the app using a deeplink, which has the side-effect of reloading the app.

In reality, when the app is opened, you should display an "applicational" notification (a feedback message or any other custom banner).

To achieve this, you need to use the "Entities.InFocusDisplayOption.NONE" value on the "InAppFocusOption" input parameter when calling "Register". This way, the Received event will be triggered and you are free to handle it in any manner that fits your needs (even by navigating to any screen, without a reload).

Is this an acceptable solution? Please let us know!

Best regards,

Carlos Simões


Hi Carlos.

This weekend I decided to manage the push notification without using deeplinks. So I came back using the RawPayload and handling the open notification click by myself. I was not satisfied losing the app screen stack (back button closes the app). This way I got everything on my way and it is work fine now.

I really appreciated your help and attention.

I hope someday I can help you and others this way too.

Cheers

Luciano Guimaraes

Solution

That's OK, Luciano.

I was hoping this last suggestion would be make things perfect for your scenario, but at least you found an alternative.

Be sure to let us know when you need help!

Best regards,

Carlos Simões

Solution

Yes! it is working now; using the RedirectToURL with parameter NotificationOpenedResult.Notification.Payload.LaunchUrl