react-native-google-nearby-messages
react-native-google-nearby-messages copied to clipboard
[BUG] If Device A publishes again after initial load, it disconnects from Device B
Bug
I have read the Troubleshooting page: Yes
Describe the bug When I try to publish a stringified object on Device A after it published on the initial load, it seems to drop Device A's connection with Device B
To Reproduce Steps to reproduce the behavior:
- Publish a stringified object on the device A, and see from device B that Device A has dropped
Expected behavior Device A and Device B should remain connected after the subsequent publish
Logs
iOS:
2020-10-12 21:15:37.826 [info][tid:main][RCTRootView.m:294] Running application example ({
initialProps = {
};
rootTag = 1;
})
2020-10-12 21:15:37.854188-0700 example[8814:1181360] [] nw_socket_handle_socket_event [C3.1:1] Socket SO_ERROR [61: Connection refused]
2020-10-12 21:15:37.855988-0700 example[8814:1181360] [] nw_socket_handle_socket_event [C3.2:1] Socket SO_ERROR [61: Connection refused]
2020-10-12 21:15:37.856414-0700 example[8814:1181355] [] nw_connection_get_connected_socket [C3] Client called nw_connection_get_connected_socket on unconnected nw_connection
2020-10-12 21:15:37.856450-0700 example[8814:1181355] TCP Conn 0x280751800 Failed : error 0:61 [61]
2020-10-12 21:15:38.453 [info][tid:com.facebook.react.JavaScript] Running "example" with {"rootTag":1,"initialProps":{}}
2020-10-12 21:15:38.486759-0700 example[8814:1181346] [] nw_socket_handle_socket_event [C5:1] Socket SO_ERROR [61: Connection refused]
2020-10-12 21:15:38.488500-0700 example[8814:1181352] [] nw_connection_get_connected_socket [C5] Client called nw_connection_get_connected_socket on unconnected nw_connection
2020-10-12 21:15:38.488556-0700 example[8814:1181352] TCP Conn 0x280755ec0 Failed : error 0:61 [61]
GNM_BLE: Checking Bluetooth Permissions...
GNM_BLE: CBCentralManager did update state with 5
2020-10-12 21:15:38.511386-0700 example[8814:1181360] [CoreBluetooth] XPC connection invalid
2020-10-12 21:15:38.513 [info][tid:com.facebook.react.JavaScript] Connecting...
GNM_BLE: Connecting...
2020-10-12 21:15:38.517 [info][tid:com.facebook.react.JavaScript] Connected!
2020-10-12 21:15:38.517 [info][tid:com.facebook.react.JavaScript] Subscribing...
GNM_BLE: Subscribing...
2020-10-12 21:15:38.519 [info][tid:com.facebook.react.JavaScript] Subscribed!
2020-10-12 21:15:38.521 [info][tid:com.facebook.react.JavaScript] Publishing "Alex’s iPhone"...
GNM_BLE: Publishing...
2020-10-12 21:15:38.521 [info][tid:com.facebook.react.JavaScript] Published "Alex’s iPhone"!
2020-10-12 21:15:39.863897-0700 example[8814:1181352] [CoreBluetooth] API MISUSE: <CBCentralManager: 0x281944540> has no restore identifier but the delegate implements the centralManager:willRestoreState: method. Restoring will not be supported
2020-10-12 21:15:39.866164-0700 example[8814:1181353] [CoreBluetooth] WARNING: <CBPeripheralManager: 0x28034c000> has no restore identifier but the delegate implements the peripheralManager:willRestoreState: method. Restoring will not be supported
2020-10-12 21:15:39.867249-0700 example[8814:1181353] [CoreBluetooth] API MISUSE: <CBPeripheralManager: 0x28034c000> can only accept this command while in the powered on state
GNM_BLE: Found message!
GNM_BLE: Found message!
2020-10-12 21:15:52.049 [info][tid:com.facebook.react.JavaScript] Found: {"deviceName":"iPod touch","text":"Useless Placeholder"}
2020-10-12 21:15:52.060 [info][tid:com.facebook.react.JavaScript] Found: {"deviceName":"iPod touch"}
2020-10-12 21:15:58.749705-0700 example[8814:1181198] [Snapshotting] Snapshotting a view (0x109f08180, _UIReplicantView) that has not been rendered at least once requires afterScreenUpdates:YES.
2020-10-12 21:16:00.531677-0700 example[8814:1181360] [general] Connection to daemon was invalidated
GNM_BLE: Publishing...
(this is when device gets "lost")
React Native:
[Mon Oct 12 2020 21:15:50.501] LOG Running "example" with {"rootTag":1,"initialProps":{}}
[Mon Oct 12 2020 21:15:50.502] LOG Connecting...
[Mon Oct 12 2020 21:15:50.502] LOG Connected!
[Mon Oct 12 2020 21:15:50.503] LOG Subscribing...
[Mon Oct 12 2020 21:15:50.503] LOG Subscribed!
[Mon Oct 12 2020 21:15:50.503] LOG Publishing "iPod touch"...
[Mon Oct 12 2020 21:15:50.503] LOG Published "iPod touch"!
[Mon Oct 12 2020 21:15:52.550] LOG Found: {"deviceName":"iPod touch","text":"Useless Placeholder"}
[Mon Oct 12 2020 21:15:52.710] LOG Found: {"deviceName":"iPod touch"}
[Mon Oct 12 2020 21:15:52.278] LOG Found: {"deviceName":"Alex’s iPhone"}
[Mon Oct 12 2020 21:16:06.916] LOG Found: {"deviceName":"Alex’s iPhone","text":"Moo"}
[Mon Oct 12 2020 21:16:06.919] LOG Lost: "{\"deviceName\":\"Alex’s iPhone\"}"
"react": 16.11.0 ,
"react-native": 0.62.2,
"react-native-google-nearby-messages": 0.10.20
Interesting, I haven't experienced this dropping in my production apps. Do you experience the issue with the app open on both devices and the message suddenly dropping? Is there some kind of rerender or maybe it has to do with how you've implemented the logic? Are you using hooks?
Hey @LeviWilliams , yeah this happens when the app is open on both devices.
I modified the example app to give this a try.. I'm still new with hooks so I might've made a mistake somewhere:
let meObj = {};
const TextInput = () => {
const onSubmitEditing = async (text) => {
meObj.text = text;
await publish(JSON.stringify(meObj));
};
const [value, onChangeText] = React.useState('Useless Placeholder');
return (
<TextInput
style={{ height: 40, borderColor: 'gray', borderWidth: 1 , color: 'black'}}
onChangeText={text => onChangeText(text)}
onSubmitEditing = {(event) => (onSubmitEditing(event.nativeEvent.text))}
value={value}
/>
);
};
export default function App() {
const [nearbyMessage, setNearbyMessage] = useState('');
const [textMessage, setTextMessage] = useState('');
useNearbyErrorCallback(
useCallback((kind, message) => {
Alert.alert(kind, message);
}, []),
);
const _connect = useCallback(async () => {
console.log('Connecting...');
await connect({
apiKey: API_KEY,
discoveryModes: ['broadcast', 'scan'],
discoveryMediums: ['ble'],
});
console.log('Connected!');
return () => disconnect();
}, []);
const _publish = useCallback(async () => {
const deviceName = await getDeviceName();
meObj.deviceName = deviceName;
console.log(`Publishing "${deviceName}"...`);
await publish(JSON.stringify(meObj));
console.log(`Published "${deviceName}"!`);
}, []);
const _subscribe = useCallback(async () => {
console.log('Subscribing...');
await subscribe(
(m) => {
m = JSON.parse(m);
setNearbyMessage(m.deviceName);
setTextMessage(m.text);
console.log(`Found: ${JSON.stringify(m)}`);
},
(m) => {
setNearbyMessage('');
setTextMessage('');
console.log(`Lost: ${JSON.stringify(m)}`);
},
);
console.log('Subscribed!');
}, []);
const _checkPermissions = useCallback(async () => {
const permission = await checkBluetoothPermission();
const available = await checkBluetoothAvailability();
Alert.alert(
'Bluetooth Permissions:',
`Granted: ${permission}, Available: ${available}`,
);
}, []);
useEffect(() => {
const start = async () => {
try {
await _checkPermissions();
await _connect();
await _subscribe();
await _publish();
} catch (e) {
Alert.alert(
'Unknown error occured while connecting!',
JSON.stringify(e.message ?? e),
);
}
};
start();
return () => disconnect();
}, [_connect, _subscribe, _publish, _checkPermissions]);
return (
<View style={styles.container}>
<Text style={styles.welcome}>☆GoogleNearbyMessages example☆</Text>
{TextInput()}
<Text style={styles.welcome}>Nearby Message:</Text>
<Text style={styles.instructions}>{nearbyMessage}</Text>
<Text style={styles.welcome}>Text Message:</Text>
<Text style={styles.instructions}>{textMessage}</Text>
</View>
);
}
Well, I put the TextInput component directly in the return statement, changed onSubmitEditing
to onEndEditing
, and that seems to have fixed it so I'll be closing this. Thanks!
Actually, upon doing this several times, the issue occurred again. I reverted back to the original example, published a simple string with a button component, and I ran into the same issue.. Do we have to do anything before publishing a message again?
@alexzkazu Yes, if you're switching what you're publishing or the component is remounting before a new publish you need to call "unpublish()" to make sure all existing publications are removed. "Make sure to unpublish, disconnect and remove any listeners as they won't be removed automatically!" - from the docs.
Just a piece of advice too - from what I can gather there this is kind of a complex way to achieve what you're trying to do. I would isolate the text input just so it's strictly a component and doesn't handle any logic and have a useEffect hook waiting for a new message or just pass down your publish logic function through props into the component. Then it's a lot easier to debug and see the flow as well. Seems to be a problem with how you're implementing it.
@yippiekaiyay were you able to resolve this issue?