Hi there!
If you've been working with React Native, you've likely encountered emulator issues. You run the React Native command, but the emulator isn’t detected. Even after setting all the necessary environment variables in your .zshrc, .bash_profile, or similar files, it still doesn’t work.
Here are some common problems and fixes:
-
Emulator Not Found: This can happen if the Android SDK path isn't correctly set. Double-check that the
ANDROID_HOMEandPATHenvironment variables point to the correct directories. You can add these lines to your.zshrcor.bash_profile:
export ANDROID_HOME=$HOME/Library/Android/sdk export PATH=$PATH:$ANDROID_HOME/emulator export PATH=$PATH:$ANDROID_HOME/tools export PATH=$PATH:$ANDROID_HOME/tools/bin export PATH=$PATH:$ANDROID_HOME/platform-toolsAfter making these changes, restart your terminal or run
source ~/.zshrc(orsource ~/.bash_profile). -
Watchman Errors: Sometimes, Watchman—Facebook’s file watching service—can cause issues with stale file caches. To fix this, run:
watchman watch-del-allThen, restart your React Native server.
-
adb reverseto Connect tolocalhost: If your app cannot connect tolocalhostfrom within the Android emulator, you might need to run:
adb reverse tcp:8081 tcp:8081This command routes traffic from the emulator to your local machine. Make sure
adbis accessible from your terminal. -
Clear Cache and Rebuild: If you still face issues, try clearing the cache and rebuilding the project:
npm start -- --reset-cache cd android && ./gradlew clean cd ios && xcodebuild cleanThen run your React Native app again.
-
Using
react-native run-androidorrun-iosDirectly: If the emulator is not starting correctly from your IDE or terminal, try running the app directly with:
npx react-native run-android npx react-native run-ios
Debugging these issues can be frustrating, but these steps have helped me solve many common problems.
I created an easy-to-use script too
const {spawn, exec} = require('child_process');
const path = require('path');
// Define paths
const projectPath = path.resolve();
// Define commands
const watchDelCommand = `watchman watch-del '${projectPath}'`;
const watchProjectCommand = `watchman watch-project '${projectPath}'`;
// Function to execute commands
const clearWatchman = () => {
// Execute watch-del command
exec(watchDelCommand, (error, stdout, stderr) => {
if (error) {
console.error(`Error executing watch-del command: ${error.message}`);
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
return;
}
console.log(`watch-del command executed successfully: ${stdout}`);
// Execute watch-project command
exec(watchProjectCommand, (error, stdout, stderr) => {
if (error) {
console.error(
`Error executing watch-project command: ${error.message}`,
);
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
return;
}
console.log(`watch-project command executed successfully: ${stdout}`);
});
});
};
async function reverseAdb() {
console.log('Running... adb reverse tcp:8080 tcp:8080');
// After the emulator has started adb reverse tcp:8080 tcp:8080
const adbReverse = spawn('adb', ['reverse', 'tcp:8080', 'tcp:8080']);
await new Promise((resolve, reject) => {
let output = '';
adbReverse.stdout.on('data', data => {
output += data.toString();
});
adbReverse.on('close', () => {
resolve();
});
adbReverse.stderr.on('error', reject);
}).catch(error => console.error('Error reversing ADB port to 8080:', error));
}
async function runEmulator() {
try {
clearWatchman();
// Check for running emulator
const adbDevices = spawn('adb', ['devices']);
const devices = await new Promise((resolve, reject) => {
let output = '';
adbDevices.stdout.on('data', data => {
output += data.toString();
});
adbDevices.on('close', () => {
resolve(output.includes('emulator'));
});
adbDevices.stderr.on('error', reject);
});
if (devices) {
console.log('Emulator is already running');
reverseAdb();
return;
}
// Get list of available emulators
const emulatorList = spawn('emulator', ['-list-avds']);
const emulatorName = await new Promise((resolve, reject) => {
let output = '';
emulatorList.stdout.on('data', data => {
output += data.toString();
});
emulatorList.on('close', () => {
const lines = output.split('\n').filter(Boolean); // Filter out empty lines
if (lines.length === 0) {
reject(new Error('No AVDs found'));
} else {
resolve(lines[lines.length - 1]); // Get the last non-empty line
}
});
emulatorList.stderr.on('error', reject);
});
// Start the emulator in detached mode
const emulatorProcess = spawn('emulator', ['-avd', emulatorName], {
detached: true,
stdio: 'ignore',
});
emulatorProcess.unref(); // Allow the parent process to exit independently of the child
reverseAdb();
console.log(`Starting emulator: ${emulatorName}`);
} catch (error) {
console.error('Error running emulator:', error);
}
}
runEmulator();
// package.json
"scripts": {
...
"dev:android": "yarn android:emulator && npx react-native@latest start",
"android:emulator": "node runEmulator.js",
...
},
By using the script above, you can run both the emulator and React Native simultaneously.
Thanks for reading!
Top comments (0)