Expo: Back button closes standalone Android apps after being closed due to memory pressure in the background

Created on 23 May 2018  Â·  61Comments  Â·  Source: expo/expo

Hello!

No Snack because it works great in Expo, however I built a version of the NavigationPlayground app where I can reproduce the issue : https://expo.io/@phorque/NavigationPlayground (the APK is here https://exp-shell-app-assets.s3-us-west-1.amazonaws.com/android%2F%40phorque%2FNavigationPlayground-dfc90ac0-5e97-11e8-9603-0a580a780605-signed.apk )

I also made a small test app with Sdk 27 here https://expo.io/@phorque/lol2 (the code can be found here https://github.com/phorque/test-expo-navigation-bug and the APK is here https://exp-shell-app-assets.s3-us-west-1.amazonaws.com/android%2F%40phorque%2Flol2-42cbd554-5ea1-11e8-bb3e-0a580a780305-signed.apk )

Environment

Environment:
  OS: Linux 4.13
  Node: 8.11.1
  Yarn: 1.2.1
  npm: 5.6.0
  Watchman: Not Found
  Xcode: N/A
  Android Studio: Not Found

Packages: (wanted => installed)
  expo: 26.0.0 => 26.0.0
  react: 16.3.0-alpha.1 => 16.3.0-alpha.1
  react-native: https://github.com/expo/react-native/archive/sdk-26.0.0.tar.gz => 0.54.2

Diagnostics report:
  https://exp-xde-diagnostics.s3.amazonaws.com/phorque-a3331f72-2433-4d7a-8181-8d4487f63e7b.tar.gz

The issue occurs on Android standalone app, I couldn't test it on iOS.

Steps to Reproduce

Every time the application reloads after it was backgrounded the back button always close the app. The best way to reproduce it is to:

  • set the background process limits to "No background process" in developper options ;
  • open the app (ex NavigationPlayground)
  • switch to another app to put the first one in background
  • go back to the first app
  • click on a subroute (for example the "Stack example" in NavigationPlayground)
  • press the back button.

The process is pretty much the same with my small test app :

Before background
  • open the app
  • click on profile
  • click on the back button
  • the app goes back to users
After the app is reloaded from background
  • click on profile
  • click on the back button
  • the app closes

Expected Behavior

I'd expect the app to goes back to the main menu.

Actual Behavior

The app close and never goes back to the main menu.

Reproducible Demo

https://expo.io/@phorque/NavigationPlayground and https://expo.io/@phorque/lol2

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';

class Users extends React.Component {
  render() {
    return (<Text>Users</Text>)
  }
}

class Profile extends React.Component {
  render() {
    return (<Text>Profile</Text>)
  }
}


const Home = createBottomTabNavigator(
  {
    Users,
    Profile
  }
);

const MainNavigator = createStackNavigator(
  {
    Home,
  }
);

export default MainNavigator;

Stuff I already tried

I tried a lot of stuff x)

  • pretty much all combinations of navigators
  • setting the BackHandler event by hand to make it always return true
  • setting the BackHandler event in a setInterval and make it always return true so I'm sure I wasn't hijacked by another library (of course react-navigation stops working with this solution, it was just to investigate)
  • make the BackHandler event of react-navigation always return true
  • I tried react-navigation ~1.5 and ~2.0
  • I tried with Expo SDK26 and Expo SDK27

Before the application is backgrounded the BackHandler events are fired and I can successfully prevent the app from closing at all (it's not the behavior I intended at first, but I was pretty desperate), however if the application reloads after being backgrounded the BackHandler doesn't seem to fire at all and the app always close, whatever I do.

AFAIK, all people who tested the app had the same behavior. I also can reproduce this issue in an emulator. Also, the NavigationPlayground on the PlayStore works great, so I'm really confused :c

Please let me know if you need more explanations or tests from me! Thanks a lot for your great work :3

Android

Most helpful comment

Don't know if this is related but I'm having the same issue when I import firebase (no in an Standalone App).
Like this issue: react-navigation#4364

ps.: It works correctly if when in debug mode.

EDIT:

I have found a workaround for this problem just changing the way I import the firebase to:

import firebase from "@firebase/app"
import "firebase/auth"
import "firebase/database"
...

https://forums.expo.io/t/issues-between-react-native-app-and-firebase/11539/2

All 61 comments

I have same problem, my setup:
react-navigation: 2.0.0
expo: sdk 27
react: 16.3.1
react-native: https://github.com/expo/react-native/archive/sdk-27.0.0.tar.gz

After some discussion here https://github.com/react-navigation/react-navigation/issues/4329 I'm pretty sure this issue is related to Expo and not react-navigation.

It may also be related to this issue https://github.com/react-navigation/react-navigation/issues/4364

minimal repro

import React from 'react';
import { View, Text, BackHandler } from 'react-native';

class App extends React.Component {
  componentDidMount() {
    BackHandler.addEventListener('hardwareBackPress', function() {
      return true;
    });
  }

  render() {
    return (
      <View><Text>I am a text</Text></View>
    );
  }
}

export default App;

needs to be run in standalone app

More clues: I tried to detach my app and I tested both a debug build and a release build, on the debug build I couldn't reproduce the issue.

Running into the same issue as well - after app is backgrounded for a while and resumed, the back button always closes the app, and does not trigger React-Navigation or a custom back handler.

Any known workarounds?

Same issue here. All works ok on the Expo client, but in standalone, pressing back button exits the app.

Using SDK v 28.0.0

Hi all, just want to acknowledge we've seen and reproduced this error. We will try to look into a fix as soon as we can but cannot promise it on any certain timeline.

Let me know if you want more tests and stuff like that :) thanks for you efforts!

Don't know if this is related but I'm having the same issue when I import firebase (no in an Standalone App).
Like this issue: react-navigation#4364

ps.: It works correctly if when in debug mode.

EDIT:

I have found a workaround for this problem just changing the way I import the firebase to:

import firebase from "@firebase/app"
import "firebase/auth"
import "firebase/database"
...

https://forums.expo.io/t/issues-between-react-native-app-and-firebase/11539/2

Same here. When running the application in debug mode it works as expected, but when running in non-dev mode. It just closes the app, it just ignores all the Back button handlers. I'm also importing Firebase, so it must be related to the issue. I can't imagine how!

Just for the record, my project is also using Firebase

Tried solution provided by @gnumarcelo and worked! Weird...

+1.....please fix it.....i am facing this on detached expo app and that too both with dev mode turned on and off. Using firebase as well.. @esamelson

I downgraded to [email protected] and suddenly everything worked........

I have this issue and don't use firebase at all.

looks like derz a huge messup. One of my projects uses [email protected] but still facing this problem.

Workaround provided by @gnumarcelo on https://github.com/expo/expo/issues/1786#issuecomment-401362246 worked for me.

Tried #1786 (comment) but didnt worked for me. Any news here?

@om1 try downgrading firebase to different versions?

Funcionou Perfeitamente,
Thanks! @gnumarcelo

@gnumarcelo solution still not works for me. To which version should i downgrade firebase or what version are u guys using?

I'm actually tempted to import Firebase in my project that doesn't need Firebase at all just to see if it makes things better x)

@om1 "firebase": "^5.0.4"

Alright i'm using "firebase": "^5.3.0". I try to downgrade and report again.

Nothing has changed. App still closes after pressing the android back button.

@om1
react-native init --version="0.55.4"  
npm install --save firebase

"dependencies": {
"firebase": "^5.3.1",
"lodash": "^4.17.10",
"react": "16.3.1",
"react-native": "0.55.4",
"react-native-animatable": "^1.3.0",
"react-native-router-flux": "^4.0.0-beta.42",
"react-redux": "^5.0.7",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0"
},

1 - CREATE A EXTERNAL FILE:

import firebase from "@firebase/app"
import "firebase/auth"
import "firebase/database"

var config = {
  apiKey: "",
  authDomain: "",
  databaseURL: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: ""
};

const Firebase = firebase.initializeApp(config);

export default Firebase;

2 - IN YOUR CLASS
import firebase from '../ YOUR FOLDER /firebase';

Still facing this issue. Maybe i'm doing something wrong with the imports...

Folder structur:

firebase/
firebase.js
auth.js
db.js
index.js

pages/
HomePage.js
Settings.js

This is what my firebase.js looks like:

import firebase from "@firebase/app"
import 'firebase/auth';
import 'firebase/database';

const config = {
    apiKey: "",
    authDomain: "",
    databaseURL: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: ""
};

if (!firebase.apps.length) {
    firebase.initializeApp(config);
}

const db = firebase.database();
const auth = firebase.auth();

export {
    db,
    auth,
    firebase
};

auth.js just imports auth from firebase.js and exports some firebase auth operations:

import {auth} from './firebase';

// Sign Up
export const doCreateUserWithEmailAndPassword = (email, password) =>
    auth.createUserWithEmailAndPassword(email, password);
...

db.js is importing db and firebase from firebase.js and exports some db operations:

import {db, firebase} from './firebase';

export const doCreateUser = (userId, username, email) =>
    db.ref(`users/${userId}`).set({
        username,
        email
    });
... 

and my index.js is just exporting auth, db and firebase for later use:

import * as auth from './auth';
import * as db from './db';
import * as firebase from './firebase';

export {
    auth,
    db,
    firebase,
};

Then in my HomePage.js and Settings.js i import db and auth from index.js and go on with my app logic...

import {db, auth} from "../firebase";

Would be grateful if someone can give me a hint.

Finaly got it to work! Downgrade firebase to "^5.0.3" did it! This whole mess up begins with firebase "^5.0.4". At least for me...

having this issue on SDK 27. I don't use firebase. Any updates for later sdks?

I was having the same issue, i had to downgrade firebase to version 5.0.3

Got this problem and found out that some lines of codes that include "Moment" package was the source of the problem

Does firebase has dependency on moment package? How is downgrading firebase solving the issue?
@fserafa

I don't think so, I'm not using firebase in my project. @themakerman

I did more research and moment is not the reason, I had some imports working together with moment and after I removed everything the problem was gone, then I added it all again and started removing one by one and the problem is with this import :

import 'core-js/es6/symbol';

Can't remember why I used this import, or maybe it was a coworker, I don't know yet, but now the problem is gone and I'm still using moment.

I got the same problem using

  "dependencies": {
    "expo": "^29.0.0",
    "expokit": "1.5.0",
    "firebase": "^5.4.2",
    "react": "^16.3.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-29.0.0.tar.gz",
    "react-navigation": "^2.11.2",
  },

The hardwareBackPress event handler on BackHandler is never called. :-/

Even i changed the firebase version, this issue still there

I just want to add that it also reproduces on non-standalone apps.
I found this issue in stack overflow (was having the same issue).

downgrading firebase from 5.3.1 to 5.0.3 solved my problem.

Any update on this? Or a workaround? It's a pretty bad issue. I can reproduce this on the android standalone app but not when using the expo client. I don't have firebase installed.

Same here, I think it's the most common bug users of our app report :c

I still have the same issue @victorgoya I did all of the steps that you performed and It's crazy, and I'm not using firebase as well

I'm not using firebase as well, but have the same problem.

Digging this BackHandler problem long long time, I found default expo app(sample app that you can install through 'expo init') has the same problem.

See the videos first.

Initial Launch(or restart app after manually kill the app using task manager)
https://youtu.be/espHwOxplvk
-> back button works well by moving to previous tab navigation.

Restart after android kill the app due to lack of resource
https://youtu.be/H9hxjkNXslo
-> back button always sends the app to the background.

default project doesn’t use firebase at all.

Some more test detail:

  • I tried to add event handler manually by ‘BackHandler.addEventListner’ after restart. but when I press back button, the event handlers are all skipped(I never removed the handler).
  • I have tested on real devices such as Galaxy S9, Galaxy S4, and Mi5.

-> I concluded this is not a specific code/device issue, but Expo or React Navigation Issue(if anyone has used React Navigation without Expo, please let me know!).

The workaround described by @gnumarcelo worked for me for some screens, but not for tab screens, where the default behaviour (going to the first tab) is kept.

However, this workaround also caused me significant problems, like failure writing blobs to firestore, so I cannot use it.

Just wanted to chime in that I am seeing this issue on expo 31.0.5, react-navigation 2.18.0. Background processes set to 0 means back button exits the app on resume.

Also experiencing this on a brand new app made via expo. Definitely don't use firebase in this app (yet). Hoping for a quick resolution, as its visible enough to consider abandoning expo mere days after starting development.

@npike - can you provide an apk?

also can you describe the exact problem that you are seeing @npike? it sounds like people in this thread are describing a variety of similar but distinct issues

Sure. Bear with me as I am new to expo/react. Is there a way I can share the APK privately?

    "expo": "^31.0.2",
    "react": "16.5.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-31.0.0.tar.gz",
    "react-native-image-view": "^2.1.1",
    "react-native-material-textinput": "^1.1.0",
    "react-navigation": "^3.0.0"

On a fresh start of the app, when navigating from the first screen to a second screen, pressing the physical back button exits the app instead of navigating backwards.

just downgrade using [email protected] it's work for me

@npike - if you can share the repository that would be more helpful even

I'm having the same problem with back button exiting app on Android.
Steps to reproduce:

  1. expo init (select tab example)
  2. replace createSwitchNavigator with createStackNavigator, add another screen to the stack navigator
  3. add a button which should navigate to the new screen on press
  4. build APK, install and launch, tap on button to navigate to next screen, tap back button - everything works as expected
  5. either open few RAM intensive apps, or go to developer settings on Android and disable background processes, launch your app again
  6. navigate to next screen, tap back button (Android system one, not the one in the status bar) - app exits

Repo with the code: https://github.com/ljuborados/back_handler_test
APK built with expo build:android: https://ufile.io/mw6ec
Video of the issue with the same APK, running on Note 9: https://youtu.be/tAK-Q0yiAcM

Thank you for your hard work, if I can do anything more to help please let me know!

@brentvatne @ide @AdamJNavarro @jesseruder @esamelson

I'm also seeing this issue with the default "Tabs" project and our App, which we just released to our customers through iOS/Android app stores. Leaving the app in the background for something like 1-2 hours and them coming back will cause pressing the Back Button to close the app. All calls to react-navigation don't work.

Here's a more reliable way (using split-screen mode) to reproduce this issue with the default "Tabs" project (Android v7.0+, Expo 31 SDK):

  1. Open your app.
  2. Click on the different tabs to navigate to the different screens and press the Back Button. It should behave as expected.
  3. Activate split-screen mode by long pressing the Square button at the bottom of the Android device. This will cause the app to reload (I believe this can simulate the "memory pressure" scenario that everyone else in this thread mentioned)
  4. Exit split-screen mode. This will again cause the app to reload.
  5. Click on the different tabs to navigate to the different screens.
  6. Press the Back button. App will close.

I also posted on the Expo forums here: https://forums.expo.io/t/expo-bug-after-a-crash-the-android-back-button-causes-standalone-app-to-be-put-into-the-background/16709

Did detaching to ExpoKit solve this for anybody?

@ScottDikowitz I forgot to mention, my main project is on ExpoKit, same problem.

@brentvatne @ide

I can confirm there is a couple of issues in this post because I suffered from both.

One issue wich is not the one related to the main post is that using newer versions of firebase will not allow the back button to work. It will always Close the app, even on Expo, downgrading would fix it.

The issue that really needs to be fixed is that an standalone app that has been placed in the background and then opened up again. The back button will Close the app.

Its easy reproducible by the instructions given on the main post.

@gerardo15 - thank you for your clear explanation, this thread has gotten a bit out of hand. We will look into this as soon as we can.

To everyone else -- please do not comment on this thread further unless you're adding information that will directly help us fix this problem. I think we have plenty to go on now. Thank you!

just downgrade using [email protected] it's work for me

thank you so much. It solved my problem.

@brentvatne @ide

I can confirm there is a couple of issues in this post because I suffered from both.

One issue wich is not the one related to the main post is that using newer versions of firebase will not allow the back button to work. It will always Close the app, even on Expo, downgrading would fix it.

The issue that really needs to be fixed is that an standalone app that has been placed in the background and then opened up again. The back button will Close the app.

Its easy reproducible by the instructions given on the main post.

Hi all,
Just a detail but for the standalone app issue :
even without having placed the app in background, the back button closes the app (whereas it behaves as expected when run in expo).

@brentvatne @ide
I can confirm there is a couple of issues in this post because I suffered from both.
One issue wich is not the one related to the main post is that using newer versions of firebase will not allow the back button to work. It will always Close the app, even on Expo, downgrading would fix it.
The issue that really needs to be fixed is that an standalone app that has been placed in the background and then opened up again. The back button will Close the app.
Its easy reproducible by the instructions given on the main post.

Hi all,
Just a detail but for the standalone app issue :
even without having placed the app in background, the back button closes the app (whereas it behaves as expected when run in expo).

Workaround the first issue: npm install [email protected] (even you do not use firebase, no idea why).
For wake from the background, anyone has a workaround?

I experienced the same issue with:

  • Android 8.1.0
  • Expo 31.0.2
  • Expo CLI 2.6.14

When tapping the back button, the app would exit instead of navigating back.

I also found the following in logcat, which seems to coincide with the app exiting.

01-28 02:40:45.146  4394 17682 E SQLiteDatabase: Error inserting period=4742000 target_class=com.google.android.gms.measurement.PackageMeasurementTaskService required_network_type=0 runtime=1548614445128 source=4 target_package=com.google.android.gms source_version=14799000 last_runtime=0 user_id=0 job_id=-1 requires_charging=0 tag=Measurement.PackageMeasurementTaskService.UPLOAD_TASK_TAG flex_time=2370000 task_type=0 retry_strategy={"maximum_backoff_seconds":{"3600":0},"initial_backoff_seconds":{"30":0},"retry_policy":{"0":0}}
01-28 02:40:45.146  4394 17682 E SQLiteDatabase: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: pending_ops.tag, pending_ops.target_class, pending_ops.target_package, pending_ops.user_id (code 2067)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:783)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1548)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1417)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at yxb.a(:com.google.android.gms@[email protected] (040400-223214910):148)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at yzt.a(:com.google.android.gms@[email protected] (040400-223214910):136)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at yzt.a(:com.google.android.gms@[email protected] (040400-223214910):6)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at yzt.a(:com.google.android.gms@[email protected] (040400-223214910):127)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at ywz.run(:com.google.android.gms@[email protected] (040400-223214910):4)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at rab.run(:com.google.android.gms@[email protected] (040400-223214910):21)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at rgd.run(Unknown Source:7)
01-28 02:40:45.146  4394 17682 E SQLiteDatabase:    at java.lang.Thread.run(Thread.java:764)

The app does not use Firebase, but as suggested in other comments I added it. Though I did not install the older version as suggested. I simply ran yarn add firebase which installed the version 5.8.1.

That fixed the problem... o/

@esamelson Any idea when this bug will get fixed? It's a serious problem.

Hi all, sorry for the super long followup time here. Finally had some time to dig into this, have a fix and am testing it now. It will almost certainly go out with the next SDK release but we might be able to backport it to SDK 32 as well.

Note that this issue has nothing to do with Firebase. If the issue you're seeing is fixed by or related to installing a certain version of Firebase, it's probably a different issue than the original one described here (which only occurs when "No background processes" is selected in the phone's Developer options).

I'm going to go ahead and lock this thread as it has become very noisy. If your issue has different repro steps than what's described in the original post, please open a new ticket as it probably won't be fixed by my change.

Hey all -- I've deployed the fix to our standalone app builders for SDK 32. You'll just need to rerun expo build:android (make sure you're on SDK 32) to get the fix. If you continue to experience similar issues, please go ahead and open a new ticket and fill out the details completely. I'm going to go ahead and close this as the issue is resolved.

Was this page helpful?
0 / 5 - 0 ratings