How to catch the device back key event?

Hey there,

I have a problem. I can do what’s necessary to prevent my users coming back to an already visited screen (when they don’t have to come back there), but it appears to be unsufficiant as they can come back pressing the back 'ey of their device.

Can’ t this event be catched to prevent such situations? It’s a bit problematic.

That would also avoid logged off users to come back to a screen requiring authentication. I tested this behavior with Tavola app, and they also have the problem. Dangerous for the data!

Hi @ChristopheHK

I had a use case where I had to implement a voting app. Imagine if you enter a voting booth, and you can cast your vote or not cast, but once you enter the booth and exit, you cannot enter the ‘voting booth’ screen again.

I used a logical variable in the user’s collection, whose value I set once that user visited the screen. You can do this in the editor by clicking on the screen -> ‘When user visits the screen’ -> Action, etc.

Navigation to that screen could be conditional, where your logical variable is of your choice (true/false, numerical, etc.).

Once the user voted, I then pushed the user to pass through a series of blank screens with transition as ‘none’, before ending up on the screen I desired. Again, with the same ‘When user visits the screen’ -> Action, etc., this time on the blank screen.

It worked perfectly.

The other way to do this is to not keep default action as ‘back’ via the back icon / left icon on the app bar. Instead you make the action as link to screen, even if it is the previous screen. This forces a new load of the screen and acts as a refresh.

Of course this doesn’t prevent navigation by hitting back button on user device. Only the first method I described above does.

I recommend either using a new flag column (in any table) which sets on sign-in + resets on visiting screen, or creating a ‘Flag’ collection which makes a new entry in the collection when user visits the screen. The checking condition for screen visibility is Logged in user -> count in the flag collection -> today = 0.

1 Like

Many thanks @tjd_15! I think the solution of my problem is the link to screen instead of the “back” action, I didn’t noticed that the back action does not reload the screen. That should work yes! Not sure about the ba k key of the device, as I think there’s no reload, but I’ll give it a try.

The variable in the user database is also a very good idea. Indeed, the login / log out actions work well, but the log out does not prevent the user to come back in an earlier screen. Using a variable, it should be okay.

Thanks again! :+1:t2:

Hey guys,

Can’t see how the above actions would work, because even if you had several screens, they’re not being ‘reloaded’ (they’re browser history), so user can keep hitting the back button into oblivion.

I’ve raised this issue with staff and ashley has acknowledged the issue & a fix in the pipeline …

1 Like

Hey @ajw, thanks for this info. To be honest, I didn’t read it at that time.

This ongoing fix is a good news!

1 Like

Hi @ajw

Not sure which method you meant isn’t working, but as I said in my post, the method I implemented has worked across devices for my use case (it was a PWA, didn’t create native builds).

I’m elaborating the logic I used to implement -

In my app I have Home, Screen A, Screen B & Screen C. The flow is Home -> A (entry condition check) -> B (take some action) -> C (confirmation).

B is the screen I want to protect & not have accessible from anywhere after being used exactly once. There are one two ways to access - A (before, from Home) & C (after, via browser or device back buttons).

From A - I add an additional screen A1, so new flow is A (check flag value in action button for conditional linking) -> A1 if flag false, or B if flag is true. I also create a flag variable which changes its value 'When User Visits Screen B" as described above. Once the flag variable is set, user flow will always direct user to Screen A1. You can add any text on A1 to indicate screen B has already been accessed once, so is locked.

From C - I add an addition blank screen C1, with custom action “When User Visits Screen C1, Link to Screen C”. New flow is B -> C1 -> C. Again, since only way to access C1 is through B, and since C1 immediately forces user to link to C, there is no way to access B. No matter how many times or how quickly back button is pressed, screen B is just not accessible. In reality I add a couple of blank screens with forced links, so my flow is B -> C1 -> C2 -> C. Just for added comfort.

That takes care of things logically for Screen B from both sides of my user flow.

For Screen B itself, In my case I was creating a new entry in ‘action’ collection via screen B. So I change the visibility of Action button depending on the condition where button is visible if ‘action collection-> logged in user count-> today < 1’. For me one use is the limit, so button disappears after an entry is created.

Maybe if you meant Screen B is always on your device cache or device history, as a separate page or a hyperlink separate from the app, its maybe possible from mobile device browser where entire app screen slug is exposed. Even on mobile device if a user bookmarks screen B, & directly visits screen B, then the visibility condition takes care of any further actions.

As mentioned, I’ve implemented this flow on a voting use case & I can tell you it worked fine (unfortunately can’t share loom due to it being a private app).

You can customize the flow & visibility / use-count for your specific use case.

Hope that helps.

What Im saying is, how are those screens checking for anything, when they’re not being ‘reloaded’ or clicked by user action?

“Maybe if you meant Screen B is always on your device cache or device history,”

That’s exactly what Im talking about … because if the screens aren’t being reloaded, user can right click ‘back’ through all previous pages, whether they’re logged in or not, due to browser cached pages.

I’ve just looked into visibility options and we shouldn’t have to group condition (visible = false) every page in our app … and even if we did do that, user can still ‘back’ to a blank page and that looks rubbish.

I think it’s easier if you copied those screens out, into a new (public) app, so other adalo users can test the solution … then we can test it out instead of having to build your method out for testing … because to be honest, I still cant see it a solution when the pages need to be reloaded (or user actioned) for conditional checking?

Your reply to my detailed explanation is … 1) you don’t want to build my solution, 2) you want me to make public a private app, where I invested effort in thinking about and building, 3) you want others users to test my solution … because its easier? As in, easier for me to share than for you to build?

And you’re coming to the conclusion that it won’t work based on a thought exercise - when I’ve already said it worked for me? Because its easier?

Let me be honest - I have the humility to accept I could be badly wrong, but not without seeing & understanding the effort to back up that statement. Its insulting to be so casually dismissive of the my solution without you actually having built it.

I had a use case, I built a solution for it, I shared (in a great detail) how I built it. I’ve spent time typing out my explanation as a courtesy to you and to future readers of this thread. I only replied because you said my method won’t work in your earlier message, when I know it did.

I have no incentive to show the app to anyone because my use case was tested & used in production by multiple users across multiple devices already. To repeat - it worked.

You need to invest your time to build my workaround, or build an alternative, for your own use case and share details for benefit of other Adalo users on how you cracked the code.

We know Adalo has its shortcomings - there are a lot of “we shouldn’t have to…” to implement a lot of features. But for a significant % of those features & use cases, there are ways to find workaround by thinking hard and/or implementing forum solutions. The workarounds aren’t very simple, but they work. Maybe you will need to build layers upon layers multiple conditional checks and actions on every single screen & every single component of your app - if your use case requires it - and its hard work, but once you do it’ll work.

Since you prefer a public app - I recommend seeing Lucien Tavano’s ‘Feather’ app template, purely to appreciate how well thought out the app is, and how much effort he’s invested to build truly impressive features. Its an exceptional app which taught me a lot.

Yep, in fact this solution is good but does not prevent any user to go from screen C to screen B, even with screen C1 in between. I’ve tested with my android device, and if I type several type my Huawei p30 back key, I can access screen B again… Indeed, the back key does not trigger a browser refresh/reload, so the checks in place don’t run again.

It’s maybe the case for any web app made with any technology?

Don’t fight guys :wink:

On my side I am going to check what I may have missed, in regards to your explanations. I probably missed something causing the back key to access the in between screen. Let me check!

And thanks for your explanations, appreciated :+1:t2:

Do you know how we can access the Feather app? I’d be interested in. To be honest, building the UI of the app is not so easy, so having a look at this app could be benefic in terms of inspiration

Yeah I agree…back-key on mobile or desktop doesnt trigger browser refresh. In cases if you’re very fast, you will be able to ‘see’ the B Screen.

So I implemented two workarounds -

  1. Screen C1 & C2 - both with forced actions “When user visits screen, link to …”. This puts some ‘distance’ between your confirmation screen & your action screen, to give the browser some latecy between executing the back key action & running the forced link action that the screen is forcing the browser to run.

  2. On the B Screen itself, make the action button or action group conditionally visible.

The difference in is - even if the user ‘sees’ the B Screen, he can’t perform any action on it. That’s very specific to my use case where I’m comfortable with the user seeing the screen as long as he can’t do any actions on it.

If you have a use case where you don’t want the user to be able to visit or ‘see’ the screen at all 100% of the time, then it is a current limitation in Adalo, because depending on browser speed, your key speed etc you will see screen B a few times and you’ll have to use many screens C1, C2, etc you keep between B & C.

Connect with Lucien at https://twitter.com/lucientavano & via https://billiondollar.app/ fill the form at end of page. He’s very helpful & he shares his templates for free. Truly amazing attention to detail in his UX even with complexity of his features.

1 Like

Many thanks @tjd_15 :pray:t2:

I agree, adding another “in between” screen is a good idea to add some distance. Perfect!

The Twitter for X app of Lucien is FAN-TAS-TIC!!

Because your explanation isn’t a solid solution.

No, I said it would be easier if you copied out that section to a public app (separate from your private app), where others can see your solution in action.

It would have saved your ‘explanation’.

Adalo staff have already acknowledged the problem as I created a quick video showing the issue, if they’re creating a fix, why would I build out a whole bloated app full of unnecessary conditional checks and workarounds?

… and now I see you acknowledge adalo’s limitation here, like I said in a separate post, it’s a small but significant issue.

It was a simple question, “how does your solution work when the pages aren’t being reloaded?”

No need to get all defensive.