Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BackHandler and remote debug #15497

Closed
sm2017 opened this issue Aug 15, 2017 · 43 comments
Closed

BackHandler and remote debug #15497

sm2017 opened this issue Aug 15, 2017 · 43 comments
Labels
Bug Help Wanted :octocat: Issues ideal for external contributors. Resolution: Locked This issue was locked by the bot.

Comments

@sm2017
Copy link
Contributor

sm2017 commented Aug 15, 2017

Is this a bug report?

(Yes)

Have you read the Contributing Guidelines?

(Yes)

Environment

  1. react-native -v:
react-native-cli: 2.0.1
react-native: 0.47.1
  1. node -v:
v8.1.3
  1. npm -v:
5.0.3
  1. yarn --version:
0.27.5

Then, specify:

  • Target Platform: Android
  • Development Operating System: Windows10
  • Build tools: react-native run-android

Steps to Reproduce

(Write your steps here:)

class App extends Component {
  componentDidMount() {
    BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
  }
  componentWillUnmount() {
    BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
  }
  onBackPress = () => {
    return true;
  };
  render() {
    return (
      <Text>Press back buton</Text>
    );
  }
}

If you run the code in development environment , it don't works and when you press back button , app will be closed , but in development environment if you turn on remote debug , the code works well and app not closed

Expected Behavior

(Prevent closing app on back button pressed)

Actual Behavior

(On development environment when remote debug is off it don't woks but when remote debug is on it works)

Reproducible Demo

(N/A)

@sm2017
Copy link
Contributor Author

sm2017 commented Aug 30, 2017

Any updates??

@Sean-Snow
Copy link

+1

This was referenced Sep 4, 2017
@hramos
Copy link
Contributor

hramos commented Sep 7, 2017

Can you reproduce the issue using Snack? This step is necessary for people to be able to see and debug the issue being reported.

@sm2017
Copy link
Contributor Author

sm2017 commented Sep 11, 2017

@hramos I explain in details how to reproduce the issue , I cannot reproduce the issue using Snack because there is no dev menu in Snack , so remote debug is meanless

@hramos
Copy link
Contributor

hramos commented Sep 11, 2017

You can run the Snack within the Expo Client and shake the device to trigger a menu to show up, no?

In any case, this is a community project. To answer your "any updates?" question, we'd take a look at any PR that proposes a fix.

@sm2017
Copy link
Contributor Author

sm2017 commented Sep 12, 2017

@hramos , I tried before using Expo Client , there is no dev menu , You can try it yourself
exp://expo.io/@snack/SJn2le4cZ

@dantman
Copy link
Contributor

dantman commented Sep 27, 2017

@sm2017 Is there a Symbol polyfill included by your app or any of your dependencies?

If you do, than this could be caused by issue #11968, which I have a PR to fix #15182.

Most desktop browsers support Symbol natively, so that would explain why the issue doesn't show up in dev mode where the browser's JS engine is used instead of the mobile device's (which may not have a native Symbol implementation).

@stale
Copy link

stale bot commented Nov 26, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Nov 26, 2017
@vegetarianlife
Copy link

vegetarianlife commented Nov 28, 2017

Hi, I am having the same trouble with it.
I am trying to implement custom action for back button and I have added the code like the below.
But it's getting an event when I enable "Debug JS Remotely" but it's not getting an event when I disable it. What's up?
I am trying to implement that backbutton functionality and I am having trouble with that.

componentDidMount () {
ToastAndroid.show("Event` Listener added", ToastAndroid.SHORT);
BackHandler.addEventListener('hardwareBackPress', () => this.backAndroid())
}

componentWillUnmount () {
BackHandler.removeEventListener('hardwareBackPress', () => this.backAndroid())
}

backAndroid () {
ToastAndroid.show("Welcome", ToastAndroid.SHORT);
return true
}

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Nov 28, 2017
@vegetarianlife
Copy link

@sm2017, have you resolved this issue?

@sm2017
Copy link
Contributor Author

sm2017 commented Dec 13, 2017

@howilliams No
Everybody that have same issue , Please add a +1 comment here

@ghost
Copy link

ghost commented Dec 13, 2017

Same issue here, is there any workaround ?

@Victoriayangx
Copy link

Victoriayangx commented Dec 27, 2017

i met this issue too, when i open debugger,android back button works well to go back to the previous page,but when i close debugger or release a version ,press back button just lead to exit app.Pls help to solve this issue asap,thanks.

What i do:
i found the BackHandler.android.js in react-native ,the path is : "react-native/Libraries/Utilities/BackHandler.android.js", test and found:
when i open debugger: subscriptions contains the function i wrote: this.onBackAndroid ,and the param invokeDefault is false. then it works well to goback to previous page.
when i close debugger: subscriptions is [] ,contains nothing ,and then the param invokeDefault is true.and then it lead to exitApp.

version:
"react-native": "0.46.1",

@dantman
Copy link
Contributor

dantman commented Dec 27, 2017

@Victoriayangx Please upgrade to 0.51, your likely encountering a bug that has already been fixed.

@batmanhit
Copy link

Hey, @dantman.
I found out that Version0.51 has some upgraded codes but it does not work at all.

screenshot at dec 28 19-17-03

screenshot at dec 28 19-08-50

It still doesn't work in normal mode, but it's working on 'Debug Only' mode and it's really really weird.

I have spent 2 days to track the issues and found out that it's the same on version 0.51.

I am gonna attach another screenshot when we run it in the 'Debug Mode'.
screenshot at dec 28 19-16-52

As you can see, in the debug mode, the Set are converted well to Array var but that doesn't work in normal mode.

@batmanhit
Copy link

HI, @sm2017. Have you found the round-about?

@Navneet2105
Copy link

Navneet2105 commented Dec 30, 2017

Hi @sm2017, I am facing the same issue. I am using React Navigation. When the remote debug mode is on, the back handler works perfectly,
After turning the remote debug off or in release mode of the app, the back handler doesn't work.
Have you found any way to fix this behavior?

@Victoriayangx
Copy link

Victoriayangx commented Jan 5, 2018

I changed the source code in BackHandler.android.js,then it worked.

Background:
After redux integration with react-navigation,i also met this issue.
refer:https://reactnavigation.org/docs/guides/redux

SourceCode:(react-native/Libraries/Utilities/BackHandler.android.js)
`
RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function() {
var subscriptions = [];
var invokeDefault = true;

_backPressSubscriptions.forEach(item=>subscriptions.push(item));
for (var i = 0; i < subscriptions.length; ++i) {
if (subscriptions【subscriptions.length-1-i】()) {
invokeDefault = false;
break;
}
}
// var backPressSubscriptions = new Set(_backPressSubscriptions);
// var invokeDefault = true;
// var subscriptions = [...backPressSubscriptions].reverse();
// for (var i = 0; i < subscriptions.length; ++i) {
// if (subscriptionsi) {
// invokeDefault = false;
// break;
// }
// }

if (invokeDefault) {
BackHandler.exitApp();
}
});`

@batmanhit
Copy link

batmanhit commented Jan 5, 2018

Bingo!!! This works.
Good job, @Victoriayangx .

Can you fork the repo and submit a merge request so that the developers all over the world would get updated one.

@Navneet2105
Copy link

Hey Guys. For me, this issue for Back Handler was due to a react-native-pathjs-charts package that was being used. I created a new solution and added each package one by one and kept on testing.

Path js package stopped the back handler. ES6 syntax distribution for that package worked for me. I copied that files and add that to my component and used it from there.

Same package or some other package might have caused the same for you.

@ghost
Copy link

ghost commented Jan 7, 2018

Hi Navneet,

Can you please explain me what exactly is to be done? I am using react-native-pathjs-charts in my project, so can you please explain me what is to be changed and where?

@AgNm
Copy link

AgNm commented Jan 8, 2018

@Victoriayangx Thanks a ton!!! 💃 you are my saviour

@Victoriayangx
Copy link

Victoriayangx commented Jan 10, 2018

@dantman ,
Hi, I suspect BackHandler cause App exit maybe caused by “Array.from(new Set())”.

Recently I met another issue about duplicate remove in Array.
1、By using "let newArray = Array.from(new Set( array ))" , in debug mode, the newArray shows ok ,when close debug mode or release mode, sometimes the newArray shows ok ,sometimes the newArray shows empty. it is not stable for App.
2、By using forEach & indexOf to remove the duplicate element in array, it always shows ok till now.

So,I suspect BackHandler cause App exit maybe also caused by “new Set”. So in Our React-Native Project, to achieve remove duplicate element in Array , we will not use new Set until the issue is resolved.

Hope it can help.Any advice,pls let me know.thanks.

@db-sc
Copy link

db-sc commented Mar 14, 2018

@Victoriayangx Is there any solution other than changing in the library because I am using Expo that won't allow me to make the change in the library.

@christoph-jerolimov
Copy link
Contributor

christoph-jerolimov commented Apr 30, 2018

Hi, I created a PR which fixes this issue. Maybe you can verify this this change and give a thump up for #19077.

@vyshakh
Copy link

vyshakh commented May 13, 2018

This fix worked for me. #3223 (comment)

@nimeshgurung
Copy link

nimeshgurung commented May 30, 2018

This issue occurred for me when pulling in core-js/es6/symbol in the app. Used es6-symbol instead which does not seem to conflict with babel transforms or JavascriptCore which is where I think the issue is when core-js/es6/symbol is imported.

[email protected] supports Symbol as far as I can tell but that throws another error, so can't really verify.

For other people the issue could be happening because the polyfill is being imported from a dependency, might be able to override how Symbol is being pulled in by being explicit inrn-cli.config.js.

@rayj10
Copy link

rayj10 commented Jun 26, 2018

still getting the problem and won't be able to change android folder because I'm using expo, please someone from RN, take one of the PRs here into consideration, really need it to work! :(

@princepardeep
Copy link

@Victoriayangx You are the great buddy.

Working like this in 54.2

var DeviceEventManager = require('NativeModules').DeviceEventManager;
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');

var DEVICE_BACK_EVENT = 'hardwareBackPress';

type BackPressEventName = $Enum<{
backPress: string,
}>;

var _backPressSubscriptions = new Set();

RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function () {
var invokeDefault = true;
var subscriptions = [];

// var subscriptions = Array.from(_backPressSubscriptions.values()).reverse();
_backPressSubscriptions.forEach(item => subscriptions.push(item));
for (var i = 0; i < subscriptions.length; ++i) {
if (subscriptionsi) {
invokeDefault = false;
break;
}
}

if (invokeDefault) {
BackHandler.exitApp();
}
});

@rayj10
Copy link

rayj10 commented Jul 6, 2018

Any updates on this? editing android folder shouldn't be the only way to fix this issue... it's unfair for CRNA/Expo users :$

@FibreFoX
Copy link

FibreFoX commented Jul 25, 2018

@princepardeep isn't that code this workaround? #3223 (comment)

@TranHanHieu
Copy link

I that have same issue, what is the solution?

@princepardeep
Copy link

it was working fine in my case.

change in this file
source code:(react-native/Libraries/Utilities/BackHandler.android.js)

Working like this in 54.2

var DeviceEventManager = require('NativeModules').DeviceEventManager;
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');

var DEVICE_BACK_EVENT = 'hardwareBackPress';

type BackPressEventName = $Enum<{
backPress: string,
}>;

var _backPressSubscriptions = new Set();

RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function () {
var invokeDefault = true;
var subscriptions = [];

// var subscriptions = Array.from(_backPressSubscriptions.values()).reverse();
_backPressSubscriptions.forEach(item => subscriptions.push(item));
for (var i = 0; i < subscriptions.length; ++i) {
if (subscriptionsi) {
invokeDefault = false;
break;
}
}

if (invokeDefault) {
BackHandler.exitApp();
}
});

@FibreFoX
Copy link

@princepardeep this is the same code you already posted, and which is posted in #3223 (comment) ... you should avoid re-posting the same code.

But yes, it is frustrating, that this kind of bug still exists. But instead of fixing that inside the core-file, I've added this code to my main app class:

  constructor(props){
    super(props);
    // https://github.com/facebook/react-native/issues/3223#issuecomment-355064410
    this.backPressSubscriptions = new Set();
  }

    componentDidMount() {
      if (Platform.OS === 'android') {
          // there is a bug/workaround on android https://github.com/facebook/react-native/issues/3223#issuecomment-355064410
          DeviceEventEmitter.removeAllListeners('hardwareBackPress');
          DeviceEventEmitter.addListener('hardwareBackPress', () => {
            let invokeDefault = true;
            const subscriptions = [];
      
            this.backPressSubscriptions.forEach(sub => subscriptions.push(sub));
      
            for (let i = 0; i < subscriptions.reverse().length; i += 1) {
              if (subscriptions[i]()) {
                invokeDefault = false;
                break;
              }
            }
      
            if (invokeDefault) {
              BackHandler.exitApp();
            }
          });
      
          this.backPressSubscriptions.add(this.handleAndroidHardwareBack);
      }
    }

    componentWillUnmount() {
      if (Platform.OS === 'android') {
        DeviceEventEmitter.removeAllListeners('hardwareBackPress');
        this.backPressSubscriptions.clear();
      }
    }

@TranHanHieu
Copy link

I find it unfeasible for me to create multiple listening events in different components

@christoph-jerolimov
Copy link
Contributor

There is still my 4 month old PR #19077 which fixes this... But nobody have the time to review/merge it. 😞

@TranHanHieu @princepardeep @FibreFoX Maybe you can verify if this change works for you as well and upvote the PR?

@TranHanHieu
Copy link

oke, thanks you @jerolimov !

@GitHubTracey
Copy link

@TranHanHieu,

I created an HOC to handle android back button press, then just pass on a function I want to call... I don’t actually have a viewable component to it, I return null, and then just add it to the bottom of each component I need it.

facebook-github-bot pushed a commit that referenced this issue Sep 7, 2018
Summary:
This fixes issues #18954 and #15497

The transformation from Set to (an reversed) Array does not work on Android devices when the remote debugging was started with `react-native run-android`.

<!--
  Required: Write your motivation here.
  If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged.
-->

Add the following code to your App.js and run the app with `react-native run-android` in an Android device:

```
  componentDidMount() {
    BackHandler.addEventListener('hardwareBackPress', () => {
      console.warn('Callback called. Do not close app. Do nothing at all.');
      return true; // Do not close the app.
    });
  }
```

After adding this, the app should NOT close when you press the back button. Without this fix, the app closes (which is the default behaviour).

See also the comments from Victoriayangx in #18954 and #15497.

<!--
  Does this PR require a documentation change?
  Create a PR at https://github.com/facebook/react-native-website and add a link to it here.
-->

<!--
  Required.
  Help reviewers and the release process by writing your own release notes. See below for an example.
-->

[ANDROID] [BUGFIX] [BackHandler] - Fix that BackHandler was not called on Android

<!--
  **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.**

    CATEGORY
  [----------]      TYPE
  [ CLI      ] [-------------]    LOCATION
  [ DOCS     ] [ BREAKING    ] [-------------]
  [ GENERAL  ] [ BUGFIX      ] [ {Component} ]
  [ INTERNAL ] [ ENHANCEMENT ] [ {Filename}  ]
  [ IOS      ] [ FEATURE     ] [ {Directory} ]   |-----------|
  [ ANDROID  ] [ MINOR       ] [ {Framework} ] - | {Message} |
  [----------] [-------------] [-------------]   |-----------|

 EXAMPLES:

 [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things
 [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput
 [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with
 [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word
 [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position
 [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see
-->
Pull Request resolved: #19077

Reviewed By: yns88

Differential Revision: D9692298

Pulled By: hramos

fbshipit-source-id: 4526b07a4924055ebc9c42e02615c27aa5c97fbb
gengjiawen pushed a commit to gengjiawen/react-native that referenced this issue Sep 14, 2018
Summary:
This fixes issues facebook#18954 and facebook#15497

The transformation from Set to (an reversed) Array does not work on Android devices when the remote debugging was started with `react-native run-android`.

<!--
  Required: Write your motivation here.
  If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged.
-->

Add the following code to your App.js and run the app with `react-native run-android` in an Android device:

```
  componentDidMount() {
    BackHandler.addEventListener('hardwareBackPress', () => {
      console.warn('Callback called. Do not close app. Do nothing at all.');
      return true; // Do not close the app.
    });
  }
```

After adding this, the app should NOT close when you press the back button. Without this fix, the app closes (which is the default behaviour).

See also the comments from Victoriayangx in facebook#18954 and facebook#15497.

<!--
  Does this PR require a documentation change?
  Create a PR at https://github.com/facebook/react-native-website and add a link to it here.
-->

<!--
  Required.
  Help reviewers and the release process by writing your own release notes. See below for an example.
-->

[ANDROID] [BUGFIX] [BackHandler] - Fix that BackHandler was not called on Android

<!--
  **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.**

    CATEGORY
  [----------]      TYPE
  [ CLI      ] [-------------]    LOCATION
  [ DOCS     ] [ BREAKING    ] [-------------]
  [ GENERAL  ] [ BUGFIX      ] [ {Component} ]
  [ INTERNAL ] [ ENHANCEMENT ] [ {Filename}  ]
  [ IOS      ] [ FEATURE     ] [ {Directory} ]   |-----------|
  [ ANDROID  ] [ MINOR       ] [ {Framework} ] - | {Message} |
  [----------] [-------------] [-------------]   |-----------|

 EXAMPLES:

 [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things
 [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput
 [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with
 [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word
 [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position
 [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see
-->
Pull Request resolved: facebook#19077

Reviewed By: yns88

Differential Revision: D9692298

Pulled By: hramos

fbshipit-source-id: 4526b07a4924055ebc9c42e02615c27aa5c97fbb
@christoph-jerolimov
Copy link
Contributor

PR #19077 is merged and is finally part of the latest RN release 0.58+

I hope for all of you that this issue here is fixed when you upgrade your RN version. 😄

@kelset
Copy link
Contributor

kelset commented Jan 28, 2019

Awesome! I'm going to close this for the time being, if the issue is still present please submit a new issue :)

Thanks @jerolimov!

@kelset kelset closed this as completed Jan 28, 2019
@facebook facebook locked as resolved and limited conversation to collaborators Jan 28, 2019
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jan 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Help Wanted :octocat: Issues ideal for external contributors. Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests