Expo app is working fine in expo go but crashes on after installation

I’m working on mqtt using paho library.my app is working and connected to mqtt broker in expo go but when i build app using eas and install it on device the app is not connected to mqtt broker . please help me

I recommend you upload your application by modules, removing your libraries one by 1 that may be generating this problem and generating the apk.

HomeScreen.jsx code
import React, { useContext,useEffect } from ‘react’;
import { View, Text, Switch, FlatList, TouchableWithoutFeedback } from ‘react-native’;
import { Button, Card, IconButton } from ‘react-native-paper’;
import { MaterialIcons } from ‘@expo/vector-icons’;
import { FontAwesome } from ‘@expo/vector-icons’;
import { DevicesContext } from ‘./DevicesContext’;
import Paho from “paho-mqtt”

const client = new Paho.Client(
public.mqtthq.com”, // Use your Broker URL here
Number(8083), // WebSocket Port
mqtt-receive-test-${parseInt(Math.random() * 100)}
);

const HomeScreen = ({ navigation }) => {
const { devices, setDevices} = useContext(DevicesContext);
useEffect(() => {
if (!client.isConnected()) { // Check if client is not already connected
client.connect({
onSuccess: () => {
console.log(“Connected to send!”);
},
onFailure: (error) => {
console.error(“Failed to connect for sending!”, error);
}
});
}
}, );

const toggleDeviceStatus = (deviceId) => {
const updatedDevices = devices.map((device) => {
if (device.id === deviceId) {
const newStatus = device.status === ‘on’ ? ‘off’ : ‘on’;

    const message = new Paho.Message(newStatus);  // send the status as the payload
    message.destinationName = `device/${device.id}/status`;
    client.send(message);

    return { ...device, status: newStatus };
  }
  return device;
});

setDevices(updatedDevices);

};
const removeFromHomeScreen = (deviceId) => {
const updatedDevices = devices.map((device) => {
if (device.id === deviceId) {
return { …device, addedToHome: false };
}
return device;
});
setDevices(updatedDevices);
};

return (
<View style={{ flex: 1, alignItems: ‘center’, marginTop: 30 }}>
<Text style={{ position: ‘absolute’, top: 10, left: 10, fontSize: 24, color: ‘#6203F0’ }}>
Home

  <View style={{ flexDirection: 'row', alignSelf: 'flex-end', alignItems: "center", marginTop: 10 }}>
  <Button

mode=“outlined”
onPress={() => navigation.navigate(‘AddDevices’)}
style={{ backgroundColor: ‘white’ }}> {/* You can define the style here */}
<Text style={{ fontSize: 14 }}>ADD DEVICES

<Button
mode=“text”
onPress={() => navigation.navigate(‘Settings’, { devices })}
icon={({ size, color }) => <MaterialIcons name=“settings” size={24} color={“#6203F0”} />}
>

  </View>
  <Text style={{ fontSize: 20, justifyContent: "center" }}>Devices List</Text>

  <View style={{ width: '95%' }}>
    <FlatList
      data={devices?.filter(device => device.addedToHome)}
      // Filter devices that are added to HomeScreen
      keyExtractor={device => device.id.toString()}
      renderItem={({ item: device }) => (
        <TouchableWithoutFeedback
          onPress={() => toggleDeviceStatus(device.id)}
          onLongPress={() => removeFromHomeScreen(device.id)}
        >
          <Card style={{ margin: 10, backgroundColor: "#6203F0" }}>
            <Card.Title
              title={<Text style={{ color: "white", fontSize: 20 }}>{device.name}</Text>}
              subtitle={<Text style={{ color: "white" }}>{device.status === 'on' ? "Status: On" : "Status: Off"}</Text>}
              left={() => <IconButton icon={device.status === 'on' ? 'power' : 'power-off'} iconColor='white' />}
              right={() => (
                <Switch
                  value={device.status === 'on'}
                  onValueChange={() => toggleDeviceStatus(device.id)}
                />
              )}
            />
          </Card>
        </TouchableWithoutFeedback>
      )}
    />
  </View>
</View>

);
};

export default HomeScreen;

AddDevicesScreen.jsx code
import React, { useEffect, useContext, useState } from ‘react’;
import {
View, Text, StyleSheet, FlatList,
TextInput, TouchableWithoutFeedback, ToastAndroid
} from ‘react-native’;
import { DevicesContext } from ‘./DevicesContext’;
import Paho from ‘paho-mqtt’;

const client = new Paho.Client(
public.mqtthq.com”,
Number(8083),
mqtt-receive-test-${parseInt(Math.random() * 100)}
);

export default function AddDevicesScreen() {
const {devices, setDevices } = useContext(DevicesContext);
console.log(“Initial devices:”, devices); // Log initial devices

const [isConnected, setIsConnected] = useState(false);

useEffect(() => {
    console.log("Running useEffect");
    if (!client.isConnected()) {
      client.connect({
        onSuccess: () => {
          console.log("Connected for receiving!");
          setIsConnected(true);
          client.subscribe("device/+/name");  // Wildcard subscription
          console.log("Subscribed to device/+/name");
          client.onMessageArrived = onMessage;
        },
        onFailure: (error) => {
          console.error("Failed to connect for receiving!", error);
          setIsConnected(false);
        }
      });
    } else {
      client.onMessageArrived = onMessage;
      client.subscribe("device/+/name"); // Wildcard subscription even if already connected
      console.log("Already connected. Subscribed to device/+/name");
    }
  }, []);
  

function onMessage(message) {
    console.log("Message received:", message.payloadString);
    
    const match = message.destinationName.match(/device\/(\d+)\/name/); // Parse the topic to extract the device ID
    if (match) {
      const deviceId = parseInt(match[1]);  // Convert extracted device ID to integer
      const receivedName = message.payloadString;
  
      const updatedDevices = devices.map((device) => {
        if (device.id === deviceId) {
          return { ...device, name: receivedName };
        }
        return device;
      });
  
      setDevices(updatedDevices);
      console.log(`Device name updated: ${deviceId} => ${receivedName}`);
    }
  }
  

const showToast = (message) => {
    ToastAndroid.show(message, ToastAndroid.SHORT);
};

const handleDoubleTap = (deviceId) => {
    const updatedDevices = devices.map(device =>
        device.id === deviceId ? { ...device, addedToHome: true } : device
    );
    setDevices(updatedDevices);
    showToast("Device added");
};

const handleLongPress = (deviceId) => {
    const updatedDevices = devices.map((device) => {
        if (device.id === deviceId) {
            return { ...device, addedToHome: false };
        }
        return device;
    });
    setDevices(updatedDevices);
    showToast("Device removed");
};

const renderItem = ({ item: device }) => {
    return (
        <TouchableWithoutFeedback
            onPress={() => handleDoubleTap(device.id)}
            onLongPress={() => handleLongPress(device.id)}
        >
            <View style={styles.deviceContainer}>
                <Text>Device: {device.id}</Text>
                <TextInput
                    value={device.name}
                    color="black"
                    fontSize={20}
                    editable={false}
                    onChangeText={(text) => editDeviceName(device.id, text)}
                />
            </View>
        </TouchableWithoutFeedback>
    );
};

console.log("Component rendering. isConnected:", isConnected);  // Log rendering
return (
    <View style={styles.container}>
        {isConnected ? (
            <Text style={styles.connectionStatus}>Connected to MQTT broker!</Text>
        ) : (
            <Text style={styles.connectionStatus}>Not connected</Text>
        )}
        <FlatList
            data={devices}
            keyExtractor={device => device.id.toString()}
            renderItem={renderItem}
        />
    </View>
);

}

const styles = StyleSheet.create({
container: {
flex: 1,
},
deviceContainer: {
padding: 10,
borderBottomWidth: 1,
borderBottomColor: ‘#ccc’,
},
connectionStatus: {
padding: 10,
fontWeight: ‘bold’,
color: ‘#007AFF’,
},
});
DevicesContext.jsx code
import React, { useState} from ‘react’;

export const DevicesContext = React.createContext();

const DevicesProvider = ({ children }) => {
const [devices, setDevices] = useState([
{ id: 1, name: ‘TV’, status: ‘off’, addedToHome: false },
{ id: 2, name: ‘AC’, status: ‘off’, addedToHome: false },
{ id: 3, name: ‘Light’, status: ‘off’, addedToHome: false },
{ id: 4, name: ‘Bulb’, status: ‘off’, addedToHome: false },
{ id: 5, name: ‘Fan’, status: ‘off’, addedToHome: false },
{ id: 6, name: ‘Switch’, status: ‘off’, addedToHome: false },
]);

return (
<DevicesContext.Provider value={{ devices, setDevices}}>
{children}
</DevicesContext.Provider>
);
};

export default DevicesProvider;
app.js code
import React from ‘react’;
import {NavigationContainer} from ‘@react-navigation/native’;
import {createNativeStackNavigator} from ‘@react-navigation/native-stack’;
import HomeScreen from ‘./HomeScreen’;
import AddDevicesScreen from ‘./AddDevicesScreen’;
import DevicesProvider from ‘./DevicesContext’;
import Settings from ‘./Settings’

const Stack = createNativeStackNavigator();

const App = () => {
// Uncomment the below line or define client appropriately.

return (

<DevicesProvider>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen 
          name="Home" 
          component={HomeScreen} 
          options={{ headerShown: false }}
        />
        <Stack.Screen name="AddDevices" component={AddDevicesScreen} />
        <Stack.Screen name="Settings" component={Settings} />
      </Stack.Navigator>
    
      </DevicesProvider>
);

}

export default App;

package.json

{
“name”: “esphome”,
“version”: “1.0.0”,
“main”: “node_modules/expo/AppEntry.js”,
“scripts”: {
“start”: “expo start”,
“android”: “expo start --android”,
“ios”: “expo start --ios”,
“web”: “expo start --web”
},
“dependencies”: {
@react-native-async-storage/async-storage”: “1.18.2”,
@react-navigation/native”: “^6.1.7”,
@react-navigation/native-stack”: “^6.9.13”,
@rneui/base”: “^4.0.0-rc.7”,
@rneui/themed”: “^4.0.0-rc.8”,
“expo”: “^49.0.0”,
“expo-status-bar”: “~1.6.0”,
“paho-mqtt”: “^1.1.0”,
“react”: “18.2.0”,
“react-native”: “0.72.4”,
“react-native-paper”: “^5.10.1”,
“react-native-safe-area-context”: “4.6.3”,
“react-native-screens”: “~3.22.0”
},
“devDependencies”: {
@babel/core”: “^7.20.0”,
@babel/plugin-proposal-decorators”: “^7.22.10”
},
“private”: true
}

app.json

{
“expo”: {
“name”: “ESPHOME”,
“slug”: “ESPHOME”,
“version”: “1.0.0”,
“orientation”: “portrait”,
“icon”: “./assets/icon.png”,
“userInterfaceStyle”: “light”,
“splash”: {
“image”: “./assets/splash.png”,
“resizeMode”: “contain”,
“backgroundColor”: “#ffffff
},
“assetBundlePatterns”: [
“**/*”
],
“ios”: {
“supportsTablet”: true,
“bundleIdentifier”: “com.ehsan342.ESPHOME”
},
“android”: {
“permissions”: [“INTERNET”],
“adaptiveIcon”: {
“foregroundImage”: “./assets/adaptive-icon.png”,
“backgroundColor”: “#ffffff
},
“package”: “com.ehsan342.ESPHOME”
},
“web”: {
“favicon”: “./assets/favicon.png”
},
“extra”: {
“eas”: {
“projectId”: “f4578def-c6b6-4d83-9e8a-328f506d6e07”
}
}
}
}

eas.json

{
“cli”: {
“version”: “>= 4.1.2”
},
“build”: {
“preview”: {
“android”: {
“buildType”: “apk”
}
},
“preview2”: {
“android”: {
“gradleCommand”: “:app:assembleRelease”
}
},
“preview3”: {
“developmentClient”: true
},
“production”: {}
}
}

i have same error and use this libraries

import { Button, Card, IconButton } from ‘react-native-paper’;
import { MaterialIcons } from ‘@expo/vector-icons’;
import { FontAwesome } from ‘@expo/vector-icons’;
React navigation and “react-native-safe-area-context”: “4.6.3”,
“react-native-screens”: “~3.22.0”

libraries i have, and im same problem

i fixed this mystery problem in expo 49 by adding the eas updates url even though i’m not using expo-updates

can you please share eas file