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