Ionic-framework: Hardware back button closes app on PWAs

Created on 16 Oct 2016  ·  12Comments  ·  Source: ionic-team/ionic-framework

Short description of the problem:

I'm building a PWA and when I tap the Android hardware back button the registered back button action is not triggered and the app closes. After make the DeepLinker configuration the browser can handle states correctly, but without page transitions.

Since document.addEventListener('backbutton') is cordova specific we need to find a way to handle the hardware back button and then we'll be able to make the page transitions work on this scenario.

What behavior are you expecting?

After register an action the app should handle backbutton events and trigger the action.

Steps to reproduce:

  1. Register an action with platform.registerBackButtonAction;
  2. Run the app;
  3. Tap the Android back button.
platform.registerBackButtonAction((ev) => {
  console.log(`Never triggered.`);
}, 10);

Other information:
Device: Nexus 5
OS: Android 6.0.1

Which Ionic Version? 1.x or 2.x
2.0-RC1

Run ionic info from terminal/cmd prompt:
Cordova CLI: 6.3.1
Ionic Framework Version: 2.0.0-rc.1
Ionic CLI Version: 2.1.1
Ionic App Lib Version: 2.1.1
Ionic App Scripts Version: 0.0.34
ios-deploy version: Not installed
ios-sim version: 5.0.8
OS: Mac OS X El Capitan
Node Version: v5.11.1
Xcode version: Xcode 7.3.1 Build version 7D1014

All 12 comments

Hello, thanks for opening an issue with us! This is actually expected behavior currently, although it should be discussed. When using the hardware back button or the browser back button transitions will not run, although when pressing the back button in the app itself it will animate. The reason we did this is for simplicity and the fact that with most PWA's built with different frameworks, page transitions are not run when using the hardware back button on Android or the browser back button. I will leave this issue open for discussion.

Hi @jgw96 thanks for your reply.

Currently, the biggest problem with this DeepLinker approach is when the user returns to the previous page and the entire state of the application is lost (eg. filters, scroll, etc.).

The app looks like a native app. It works offline. I can open it from my home screen. The app doesn't have the address bar. I can even receive push notifications. But, the navigation doesn't behaves like a native app and this is frustrating. I'm not a UX expert but I believe that the user expects an similar behaviour to native apps in this case.

Pokedex.org (one of the greatest PWAs, IMHO) recently fixed this hardware back button issue using the hashchange event (https://github.com/nolanlawson/pokedex.org/pull/60).

This issue is reminiscent of the days when the back button used to close Cordova applications before Ionic came along and fixed it greatly. What exactly is the issue here @jgw96 Is it a conscious decision and is there a way we can handle this ourselves?

Tacking on discussion as prompted by @jgw96 in his comments.

IMO, built-in support for browser & native back buttons with ionic2 PWAs should be high priority. While evaluating building mult-page PWAs with Ionic2, the main blocker we discovered was users would have to avoid the browser & native back buttons which is a non-starter for us.

I'm assuming there is a lot of technical work to enable this since Ionic2 doesn't rely on ng2s built-in routing. I'd like more visibility on what the current stance is on this behavior now that PWAs is suppose to be a major focus for ionic2?

@jtillman Hardware Go Back button support has been improved in the last weeks:

Can you try against nightly?

npm install ionic-angular@nightly --save

@manucorporat this issue remains.

I meet this problem too, I tried to solve this by myself. This is my solution:
At first, I write this code to app.component.ts:

app.component.ts:

history.pushState(null, null, document.URL);
window.addEventListener('popstate', () => {
        if (this.nav.canGoBack()) { //Can we go back?
          if(this.nav.length()>2){history.pushState(null, null, document.URL);}
          this.nav.pop();
        }else{
           history.go(-2);
        }
 });

There is a problem with this solution, history.go(-2) can't close the PWA launched from cell phone home screen. So I fix the code:

app.component.ts:

window.addEventListener('popstate', () => {
        if (this.nav.canGoBack()) { //Can we go back?
          if(this.nav.length()>2){history.pushState(null, null, document.URL);}
          this.nav.pop();
        }
 });

home.page.ts(The root page):

ionViewWillLeave() {
        history.pushState(null, null, document.URL);
        console.log("leave home ,add pushState");
    }

Now, the problem seems to be solved, but soon I found another question. When the modal is open, the back button will pop the page without close the modal. And I do this to fix it:

app.component.ts:

window.addEventListener('popstate', () => {
        if(dataService.runTimeCache.openedModal){
          dataService.runTimeCache.openedModal.dismiss();
          delete dataService.runTimeCache.openedModal;
          history.pushState(null, null, document.URL);
          return;
        }
        if (this.nav.canGoBack()) { //Can we go back?
          if(this.nav.length()>2){history.pushState(null, null, document.URL);}
          this.nav.pop();
        }
      });

openModal.page.ts:
```
presentModal() {
let modal = this.modalCtrl.create(modalsPage);
modal.present();
this.dataService.runTimeCache.openedModal=modal;
}

modal.page.ts:

dismiss() {
this.viewCtrl.dismiss();
delete this.dataService.runTimeCache.openedModal;
}
```

This worked!
I only used modal in my app, maybe we need to add more code when we add another UI component in the app.
This is just a temporary solution, I believe the ionic team will work this out soon.

Hello all! This has since been solved by our new IonicPage feature (previously called deeplinker) https://ionicframework.com/docs/api/navigation/IonicPage/

@jgw96
the transition is still not work

@jgw96
I have developed a PWA in ionic 3 with lazy load. IonicPage is there for each page. But hardware back button still not behave good. I am using tabs in my root component. Is there any demo of PWA in ionic 3 with IonicPage & hardware back handling?

Found demo here & also found actual problem. Lazy load demo of ionic conference app doing good with browser back button. But in my PWA, when I press browser back, all data from previous page is lost.
e.g. If there are 3 pages A, B, C. A is root.
-> Pushed B from A with navParams.
-> Then pushed C from B.
-> Now pressing browser back button to go back to B, will loose all navParams data.
-> Also realised, browser back button reloading my previous page.(Checked with life cycle events. Constructor & ionViewDidLoad called again). But in demo, only ionViewDidEnter is called.

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

Was this page helpful?
0 / 5 - 0 ratings