I am developing a React Native app that I am deploying for Android and recently encountered a crash on startup. The log indicates a TypeError related to a property shouldAutoEstablishSocketConnection being undefined.
The app without Hermes as the JavaScript engine. Here are the relevant parts of the log:
TypeError: undefined is not an object (evaluating 'i.CometChat.appSettings.shouldAutoEstablishSocketConnection'), stack: <unknown>@3551:333610 ...
The app with Hermes as the JavaScript engine. Here are the relevant parts of the log:
2024-03-06 07:25:25.129 7771-7809 ReactNativeJS com.podium E TypeError: Cannot read property 'shouldAutoEstablishSocketConnection' of undefined, js engine: hermes
... The crash seems to occur immediately upon startup, and it's unclear why shouldAutoEstablishSocketConnection is undefined since it's part of the initial configuration for CometChat, which we're using for messaging in the app. Here is a full log:
TypeError: undefined is not an object
(evaluating 'i.CometChat.appSettings.shouldAutoEstablishSocketConnection')
2024-03-06 09:05:19.664 8787-8829 AndroidRuntime com.podium E FATAL
EXCEPTION: mqt_native_modules
Process: com.podium, PID: 8787
com.facebook.react.common.JavascriptException: TypeError: undefined is not an object (evaluating 'i.CometChat.appSettings.shouldAutoEstablishSocketConnection'), stack: <unknown>@3551:333610 <unknown>@455:891 value@23:787 value@10:847 value@39:3897 <unknown>@39:693 value@39:2528 value@39:664 value@-1 at com.facebook.react.modules.core.ExceptionsManagerModule.reportException(ExceptionsManagerModule.java:65) at java.lang.reflect.Method.invoke(Native Method) at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372) at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:149) at com.facebook.jni.NativeRunnable.run(Native Method) at android.os.Handler.handleCallback(Handler.java:958) at android.os.Handler.dispatchMessage(Handler.java:99) at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:29) at android.os.Looper.loopOnce(Looper.java:205) at android.os.Looper.loop(Looper.java:294) at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:234) at java.lang.Thread.run(Thread.java:1012)
this is my app.js code
import React, {useEffect, useState} from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
import {CometChat} from '@cometchat/chat-sdk-react-native';
import {CometChatCalls} from '@cometchat/calls-sdk-react-native';
import { initParticle } from './particle';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {NavigationContainer} from '@react-navigation/native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import Login from './components/login/Login';
import SignUp from './components/register/SignUp';
import Home from './components/home/Home';
import Search from './components/search/Search';
import CreateRoom from './components/room/CreateRoom';
import EditRoom from './components/room/EditRoom';
import RoomDetail from './components/room/RoomDetail';
import Call from './components/call/Call';
import Notifications from './components/notifications/Notifications';
import {cometChatConfig} from './env';
import {showMessage, showMessageWithActions} from './services/ui';
import Context from './context';
import Compass from './images/compass.svg';
import Logout from './images/logout.svg';
import Bell from './images/bell.svg';
const Stack = createNativeStackNavigator();
const App = () => {
const [user, setUser] = useState(null);
const [roomDetail, setRoomDetail] = useState(null);
// In your context file or app-level state management
const [isInitialized, setIsInitialized] = useState(false);
const initCometChat = async () => {
const appID = cometChatConfig.cometChatAppId;
const region = cometChatConfig.cometChatRegion;
console.log("This is the appID cometChat is configured to use: ", appID);
console.log("This is the region cometChat is configured to use: ", region);
try {
// Initialize CometChat
const appSetting = new CometChat.AppSettingsBuilder()
.subscribePresenceForAllUsers()
.setRegion(region)
.autoEstablishSocketConnection(true)
.build();
await CometChat.init(appID, appSetting);
console.log("Initialization completed successfully");
//CometCall (audio & video) sign in
// Initialize CometChatCalls
const callAppSettings = new CometChatCalls.CallAppSettingsBuilder()
.setAppId(appID)
.setRegion(region)
.build();
await CometChatCalls.init(callAppSettings);
console.log('CometChatCalls was initialized successfully');
} catch (error) {
console.error("Initialization failed with error:", error);
}
};
const initAuthenticatedUser = async () => {
console.log("Initiate Authenticated User...");
const authenticatedUser = await AsyncStorage.getItem('auth');
setUser(() => (authenticatedUser ? JSON.parse(authenticatedUser) : null));
console.log("User is set");
};
useEffect(() => {
const initialize = async () => {
try {
await initCometChat();
console.log("init cometChat done");
initParticle();
console.log("init Particle done");
await initAuthenticatedUser();
console.log("init authenticated user done");
setIsInitialized(true);
} catch (error) {
console.error("Error during initialization:", error);
// Handle the error, e.g., setting an error message state to display to the user
showMessage('Error', 'Initialization error: ' + error.message);
}
};
initialize();
}, []);
const search = (navigation) => () => {
navigation.navigate('Search');
};
const notifications = (navigation) => () => {
navigation.navigate('Notifications');
};
const logout = (navigation) => () => {
showMessageWithActions({
title: 'Confirm',
message: 'Do you want to log out?',
actions: [
{text: 'Cancel'},
{text: 'OK', onPress: () => handleLogout(navigation)},
],
});
};
const handleLogout = async (navigation) => {
await CometChat.logout();
removeAuthedInfo();
navigation.reset({
index: 0,
routes: [{name: 'Login'}],
});
};
const removeAuthedInfo = () => {
AsyncStorage.removeItem('auth');
setUser(null);
};
const leaveRoom = (navigation) => async () => {
try {
await leaveCometChatGroup();
} catch (e) {
console.log(e);
}
navigation.goBack();
};
const leaveCometChatGroup = async () => {
if (roomDetail && roomDetail.createdBy.email !== user.email) {
await CometChat.leaveGroup(roomDetail.id);
} else {
showMessage('Info', 'Owner cannot leave the room');
}
};
if (user) {
return (
<Context.Provider value={{user, setUser, roomDetail, setRoomDetail}}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
options={({navigation}) => ({
headerStyle: {
backgroundColor: '#F1EFE3',
},
headerLeft: () => (
<TouchableOpacity onPress={search(navigation)}>
<Compass width={36} height={36} />
</TouchableOpacity>
),
headerRight: () => (
<View style={styles.homeHeaderRight}>
<TouchableOpacity
onPress={notifications(navigation)}
style={styles.bellBtn}>
<Bell width={24} height={24} />
</TouchableOpacity>
<TouchableOpacity onPress={logout(navigation)}>
<Logout width={24} height={24} />
</TouchableOpacity>
</View>
),
})}
/>
<Stack.Screen
name="Search"
component={Search}
options={() => ({
headerStyle: {
backgroundColor: '#F1EFE3',
},
})}
/>
<Stack.Screen
name="Create Room"
component={CreateRoom}
options={() => ({
headerStyle: {
backgroundColor: '#F1EFE3',
},
})}
/>
<Stack.Screen
name="Edit Room"
component={EditRoom}
options={() => ({
headerStyle: {
backgroundColor: '#F1EFE3',
},
})}
/>
<Stack.Screen
name="Room Detail"
component={RoomDetail}
options={({navigation}) => ({
headerStyle: {
backgroundColor: '#F1EFE3',
},
headerRight: () => (
<View>
<TouchableOpacity onPress={leaveRoom(navigation)}>
<Text style={styles.leaveQuitelyTxt}>Leave Quitely</Text>
</TouchableOpacity>
</View>
),
})}
/>
<Stack.Screen name="Call" component={Call} />
<Stack.Screen
name="Notifications"
component={Notifications}
options={() => ({
headerStyle: {
backgroundColor: '#F1EFE3',
},
})}
/>
</Stack.Navigator>
</NavigationContainer>
</Context.Provider>
);
}
return (
<Context.Provider value={{user, setUser}}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="SignUp" component={SignUp} />
<Stack.Screen name="Home" component={Home} />
</Stack.Navigator>
</NavigationContainer>
</Context.Provider>
);
};
const styles = StyleSheet.create({
homeHeaderRight: {
flexDirection: 'row',
},
bellBtn: {
marginRight: 8,
},
leaveQuitelyTxt: {
fontWeight: 'bold',
fontSize: 16,
},
});
export default App;
These are my packages and dependencies:
"@cometchat/calls-sdk-react-native": "^4.0.4",
"@cometchat/chat-sdk-react-native": "^4.0.5",
"@cometchat/chat-uikit-react-native": "^4.2.2",
"@ethersproject/shims": "^5.7.0",
"@particle-network/rn-auth": "^1.3.10",
"@react-native-async-storage/async-storage": "^1.22.2",
"@react-native-community/cli": "^12.3.6",
"@react-native-community/netinfo": "11.3.0",
"@react-native/js-polyfills": "^0.74.0",
"@react-native/metro-babel-transformer": "^0.73.15",
"@react-native/typescript-config": "0.73.1",
"@react-navigation/bottom-tabs": "^6.5.14",
"@react-navigation/native": "^6.1.12",
"@react-navigation/native-stack": "^6.9.20",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"buffer": "^6.0.3",
"emoji-mart-native": "^0.6.5-beta",
"eslint": "^8.19.0",
"ethers": "^6.11.1",
"firebase": "^10.8.0",
"idb": "8.0.0",
"metro-config": "^0.80.6",
"metro-runtime": "^0.80.6",
"prettier": "2.8.8",
"react": "18.2.0",
"react-native": "0.73.5",
"react-native-autolink": "^4.2.0",
"react-native-background-timer": "^2.4.1",
"react-native-callstats": "3.73.22",
"react-native-document-picker": "^9.1.1",
"react-native-elements": "^3.4.3",
"react-native-fast-image": "^8.6.3",
"react-native-get-random-values": "^1.10.0",
"react-native-image-picker": "^7.1.0",
"react-native-keep-awake": "^4.0.0",
"react-native-safe-area-context": "^4.9.0",
"react-native-screens": "^3.29.0",
"react-native-sound": "^0.11.2",
"react-native-svg": "^15.0.0",
"react-native-svg-transformer": "^1.3.0",
"react-native-swipe-list-view": "^3.2.9",
"react-native-vector-icons": "^10.0.3",
"react-native-video": "^5.2.1",
"react-native-video-controls": "^2.8.1",
"react-native-webrtc": "118.0.1",
"reanimated-bottom-sheet": "^1.0.0-alpha.22",
"rn-fetch-blob": "^0.12.0",
"typescript": "5.0.4",
"uuid": "^9.0.1",
"validator": "^13.11.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/babel-preset": "0.73.21",
"@react-native/eslint-config": "0.73.2",
"@react-native/metro-config": "0.73.5",
"babel-jest": "^29.6.3",
"jest": "^29.6.3",
"react-test-renderer": "18.2.0"
},
Here's what I've tried so far without success:
Checking all dependencies are up to date. Cleaning the build folder and reinstalling node modules. Verifying CometChat is correctly initialized with the provided appID and region. Tested it in debug mode where it works. Restructuring the initializations to wait in sequence. I suspect the issue might be related to how CometChat is initialized or possibly a conflict with another package, but I'm not sure how to diagnose or fix it, especially since the issue is with the release mode and not debug.
Has anyone encountered a similar issue or has any idea what might be causing this? Any help or suggestions would be greatly appreciated!